[toc]
## flex容器
### 基本特性(同grid容器)
關鍵詞:`獨占一行`、`margin自動填充`
首先設置了`display:flex`元素容器并不會改變它本身的盒子模型(不會轉換為border-box什么的,和grid-container是一致的)。


### flex容器與grid容器的富余空間管理對比
flex容器和grid容器的富余空間管理**都是**針對flex/grid容器**所開辟的空間**的。
flex容器的富余空間是指除去所有flex-item項所占據的空間外的剩余空間。

>[danger] **注意:** 富余空間并不是圖中`flex-container`的margin部分。
grid容器的富余空間是指除去grid網格外的剩余空間(注意,不是gird-item,嗯,是所有grid-item的集合再加上grid-gap)

>[danger] **注意:** 富余空間并不是圖中`grid-container`的margin部分。
---
上面我們知道了富余空間是什么,那么怎么操作富余空間呢,
我們可以通過`justify-content/align-content`(grid/flex都有)來操作父容器的富余空間
另外在API記憶上,flex和grid系統一樣都些個類似的屬性**值**,它們對應的效果分別是:
- 靠左 grid是start flex要帶前綴 flex-start
- 居中 都是center
- 靠右 grid是end flex要帶前綴 flex-end
- 讓每一個item大小一樣(space-around)
- 第一個和最后一個item分別占據容器開辟的空間的首尾,中間的item之間間距相等(space-between)
- space-evenly:讓每個item之間的間距相等(包括首尾)
以上是幾個最常用的,除此之外還有很多[點我](https://developer.mozilla.org/en-US/docs/Web/CSS/align-content)
還需要注意的一點是,grid的align/justify-content都還有一個`stretch`的值(雖然貌似毫無卵用)
,而**flex**只有align-content有這個值,且這個值是align-content的**初始值**。
### flex-container與其margin
我們已經知道一旦元素設置了`display:flex`就會成為一個`flex-container`,它會獨占一行,且如果border-box的大小不足以獨占一行會用margin填充。
So我們仍然可以對`flex-container`使用`margin:auto`來使其居中什么的。

> **再次強調:** 請注意區分flex-container的富余空間和margin,他們并不是同一個東西
### flex-flow:如何在container中放置item?
`flex-flow`是`flex-direction`和`flex-wrap`的復合起來的屬性。
其中flex-direction決定的是內部item是從左往右排列(row)還是從上往下排列(column),**一旦決定了direction,我們也就順道決定了這個flex的主軸**

而flex-wrap決定的是item排列時,若空間不夠了,換不換行。(若不換行就會被壓縮)
并且這兩個屬性都值都可以添加一個`-reverse`后綴,這表示顛倒排列的順序。
### align-items:在容器中統一管理item的富余空間
`align-items` 這個屬性能統一處理item中的**側軸的**富余空間。(**注意是item自己內部的富余空間**)
注意,這個屬性并不能對某個item進行訂制,而是會對所有item的富余空間進行相同的安排(操作)。
另外它和grid系統的api不同,這貨**只有**`align-items`,是的,只有,**并沒有`justify-items`!!**。(grid是有的)
MDN官網截圖為證

## flex-item:容器中的每一項
### flex-basis
#### 默認值:auto
一個flex-item的基礎大小,默認值為`auto`,也就是每個item自己的內容大小。
需要注意的是,flex-item并不像gird-item,它并不是一個margin-box,而是一個正常的盒模型。

#### flex-basis設置的是item在主軸上的大小
flex-basis指定并不一定是一個item的寬度,確切的說它決定的是一個item在主軸上的長度。
例如我們將`flex-direction`設置為`column`時(主軸變更為y軸)

#### 與width/height、min/max-width/height
嘛,其實basis就是width or height(根據主軸不同,有肯能是width也有可能是height)。
當設置了basis你最好就不要再設置width or height,嗯,貌似有什么兼容性bug一類的。
另外你最好也不要給這些item設置border、padding、margin,特別是當你想要使用grow或則shrink的時候,這會導致效果的不可預期。
### flex-item與margin
給flex-item設置相應的margin auto能達到和justify-content相同的效果,不過這樣的話,父容器若還有justify-content就不再影響到flex-item了。

### flex-grow和flex-shrink
嗯,這是整個flex布局中最精華的部分了,正是因為這兩個屬性,才讓Flex所代表的**伸縮**二字名副其實。
#### 默認值
```
flex-grow:0;
flex-shrink:1;
```
其中grow是生長的意思,shrink是壓縮的意思,默認情況下,item不會生長(即使存在富余空間),但是會被壓縮(flex-container開辟的空間<items所占據的空間時)
#### 關于生長和壓縮的計算
當設置了生長時,每個item增加的大小是按照下面這樣一個計算公式來計算的
```
可用空間 =(容器大小 - 所有相鄰項目flex-basis總和)
每項伸縮大小 = 伸縮基準值 + ((可用空間 / 所有相鄰項目flex-grow總和) x 此項的flex-basis值)
```
而壓縮時,是按照下面這樣計算的
```
//假如tem1-4的basis依次為100、200、200、200
//item1-4的shrink依次為1、2、3、1
所有項目之和 = 項目一(1x100) + 項目二(2x200) + 項目三(3x200) + 項目四(1 x 200) = 所有項目總和(1400)
項目二收縮因數 = 項目二(2 x 200px)/所有項目之和(1400) = 0.286
第二項移除空間 = 項目二收縮因數(0.286) x 負可用空間(-200px) = -57.142向下舍入為57。
```
##### flex-grow、flex-shrink針對的也是主軸上怎么進行伸縮
#### 和justify/align-content 的比較
首先justify/align-content是針對**flex容器的**富余空間的,
而`flex-grow`其實也是針對的其父,flex容器的,只不過相較于`justify-content`只是分配富余空間給item,它是對富余空間的利用的另外一種形式,它會消耗掉富余空間。
雖然說justify-content/align-content中的`stretch`也能達到差不多的效果,但它們最主要的作用還是分配富余空間給每個item。
另外flex-grow **并不能影響側軸**(的富余空間),`align-content`才能,并且它的默認值為`stretch`(也就是會讓item鋪滿整個側軸的富余空間)。
實際上關于側軸的富余空間,因為flex只是一個一維布局,所以要是側軸的富余空間被消耗,只會存在一種效果,那就是**stretch平鋪**(**側軸上只會有一個item**)。
---
而`flex-shrink`的功效則和富余空間完全沒有關系,它是當父容器(flex-container)開辟的空間不夠用的時候的選擇。默認情況下,它會等比例的壓縮所有item。
### align-self
首先要聲明的一點是,在flex系統中,我們只能管理flex-item側軸上的富余空間,so只有align-self這一個api沒有什么justify-self!!
相較于align-item,align-self能允許我們單獨管理某一個item中的富余空間

### 絕對項目與相對項目
> 相對項目
當`flex:auto`,即`flex:1 1 auto`時,flex-item既可伸又可縮,但它的實際寬度是基于basis之上的。

> 絕對項目
當`flex:1`,即`flex: 1 1 0`時,flex-item既可伸又可縮,并且它的basis為0,**這意味著flex-item的寬度只基于flex的生長**。

## flex和grid總結
### 盒子模型方面
>相同之處:
flex系統的flex-container和grid系統的grid-container一樣,都會讓元素起到block化的效果獨占一行(如果手動設定了固定寬度,不夠一行的部分會被margin填充)
>不同之處:
grid系統的grid-item你可以把它當做一個`margin-box`(不亂給grid-item設置grid系統中沒什么意義的寬高的話)
而flex系統的flex-item只是一個普通的盒子模型。
### 富余空間
#### 容器富余空間管理
>相同之處:
都能夠用`justify-content`、`align-content`管理container父容器的富余空間。
>不同之處:
1. grid的富余空間是除卻網格的部分,這里的網格,不僅包括每一項item,**還包括網格的gap**。
2. flex系統中justify-content和align-content的start、end不叫start、end而叫`flex-start`和`flex-end`。
3. flex系統中只有`align-content`有`stretch`值,而grid系統中justify-content和align-content都有?(但貌似grid justify-content的stretch無效?可以在template的時候使用fr達到stretch效果,或則在template中只用grid-line分區)
4. flex系統還能通過在item上設置grow來利用富余空間,雖然只是主軸上的富余空間,側軸上的仍然需要使用align-content。
#### item富余空間管理
flex的item只能進行側軸上的富余空間管理。
它只有align-self,而沒有justify-self
#### flex與側軸
flex系統中的側軸默認是平鋪的`stetch`,不論是`align-content`還是`align-item`,flex-item在側軸上永遠是從頭躺到尾。
### 其它
grid系統中的主軸側軸并不會發生交換,主軸永遠是x軸,側軸永遠是y軸。
## 附表:flex系統中的關鍵字值和默認值
>flex:none | <' flex-grow '> <' flex-shrink >'? || <' flex-basis '>
如果「flex: 0 auto」或者「flex: initial」, 則其計算值為「0 1 auto」,即「flex」**默認值**
如果縮寫「flex: 1」, 則其計算值為「1 1 0%」
如果縮寫「flex: auto」, 則其計算值為「1 1 auto」
如果「flex: none」, 則其計算值為「0 0 auto」
>flex-grow:<number>
默認值:flex-grow:0
>flex-shrink:<number>
默認值:flex-shrink:1
>flex-basis:<length> | <percentage> | auto | content
默認值 flex-basis:auto
`<length>`:用長度值來定義寬度,不允許負值
`<percentage>`:用百分比來定義寬度,不允許負值
`auto`:無特定寬度值,取決于其它屬性值
`content`:基于內容自動計算寬度
>flex-flow:<' flex-direction '> || <' flex-wrap '>
flex-direction:row | row-reverse | column | column-reverse
默認:row
flex-wrap:wrap | wrap-reverse | nowrap | nowrap-reverse
默認:nowrap
>justify-content:flex-start | flex-end | center | space-between | space-around
默認值 :flex-start
> align-content:flex-start | flex-end | center | space-between | space-around | stretch
默認值:stretch
>align-items:flex-start | flex-end | center | baseline | stretch
默認值:stretch
>align-self:auto | flex-start | flex-end | center | baseline | stretch
默認值:auto
>order:<integer>
默認值0,可以為負值
- 空白目錄
- 未處理
- webpack中的css模塊化
- CSS預處理器
- 效果
- 元素裝飾與美化
- 顏色
- checkbox
- img
- background
- clip-path
- 字體
- 文本控制
- text-indent
- letter-spacing
- word-spacing
- word-break和word-wrap
- white-space
- text-align
- text-decoration
- text-transform
- first-letter
- first-line
- 有關CSS百分單位的那些奇葩事兒
- 破壞性、包裹性、塊狀化
- 強大的absolute
- padding
- relative
- 繼承性
- fixed
- float
- BFC
- z-index
- overflow
- clip
- 最佳可訪問性隱藏
- 關于scrollHeight/Width
- 包含塊
- margin
- 布局系統
- 雜
- Flex
- Grid
- 自定義布局系統
- gutter實現思路
- 選擇器
- 偽元素和偽類
- css3
- appearance
- CSS2.1
- tmp
- 未定義行為
- 焦點元素
- outline輪廓
- 替換元素
- 盒子模型
- 塊級元素/盒子
- 標記盒子
- 容器盒子(內在盒子)
- 內聯元素/盒子
- 字母X
- line-height
- vertical-align
- font-size
- 內聯元素盒子模型新解
- line-height定義
- line-height與行內框盒子模型
- line-height與內聯元素的高度機制
- line-height值
- line-height與圖片
- vertical-align支持的屬性值及組成
- vertical-align起作用前提
- vertical-align與圖片
- vertical-align與line-height
- vertical-align前后不一的行為表現
- vertical-align實際應用
- line-height與height
- width/height與auto
- 最小內容寬度
- 最大內容寬度
- min/max-width/height注意事項
- 流:外部尺寸與內部尺寸
- 流體布局下的寬度分離原則
- height:auto
- 瀏覽器渲染原理
- 移動端