FFC (flex formatting context)
- Flexbox 布局新定義了格式化上下文,類似 BFC(block formatting context)
- 注意 : 我所指的Flexbox 是指設置了 display: flex; 或 display: inline-flex;的盒子。不是指單單設置了 display: flex; 的盒子。
- 例如,設置了 display: flex; 或 display: inline-flex的元素,和BFC一樣,不會被浮動的元素遮蓋,不會垂直外邊距坍塌等等。
與BFC的細微區別
但需要注意的是以下幾點細節,Flexbox 布局 和 Block 布局是有細微區別的
Flex box(父元素)
- Flexbox 不支持 ::first-line 和 ::first-letter 這兩種偽元素
- vertical-align 對 Flexbox 中的子元素 是沒有效果的
- float 和 clear 屬性對 Flexbox 中的子元素是沒有效果的,也不會使子元素脫離文檔流(但是對Flexbox 是有效果的!)
flex item(flex 子元素)
- 多欄布局(column-*) 在 Flexbox 中也是失效的,就是說我們不能使用多欄布局在Flexbox 排列其下的子元素(魚和熊掌不可得兼嘛)
- Flexbox 下的子元素不會繼承父級容器的寬
flex項目盒子介紹
- CSS解析器會把 定義了 display: flex; 和 display: inline-flex; 的 Flexbox 下的子元素外部裝進一個看不見的盒子里,我們通過排列這些盒子來達到排序、布局、 伸縮的目的。
- 規范中把這種盒子 稱為 flex item,而子元素中包括了 標簽節點 以及 文本節點。標簽節點很容易理解,需要注意的是文本節點。
- 默認情況下,flex 會將 連續的文本節點 裝進 flex-item 之中,使文本可以和標簽節點一起排序和定位。
- 值得注意的是,空格也是文本節點,所以 white-space 會影響Flexbox 中的布局,比如設置了white-space: pre 的Flexbox
flex-item-size 如何計算的
item-size(尺寸)為主軸方向上item的 content 再加上自身的margin 、 border 和 padding 就是這個 item 的尺寸。
位置
- flexbox 下設置了absolute的子元素的位置受3個方面的影響:
- justify-content | align-items > top、left、right、bottom=margin(優先級排序)
- 對于 Flexbox 來說,設置了position: absolute;并不會對其下的子元素產生任何影響。
image.png
- 1、2、3、5受topleftbottomright影響,4受justify-content、align-items和margin影響,6、7、8、9只受justify-content、align-items
寬或高
三種情況
- flex-basis > width[height]: 非auto(沒有元素默認值和內容); (優先級)
- width:auto、width:非auto和flex-basic(優先級比較)
- width:auto < flex-basis值
- width:auto < flex-basis(優先級)
- width:auto > flex-basis值
- width:auto > flex-basis(優先級)
- width:非auto < flex-basis(優先級)
- min-width[height]、max-width[height]、flex-basis和flex container(父元素容器尺寸)(優先級比較)
min-width[min-height]
- flex-basis > min-width[min-height] 值
- flex-basis > min-width[min-height](優先級)
- flex-basis < min-width[min-height] 值
- flex-basis < min-width[min-height](優先級)
flex container
- min-width[min-height] > flex container 值
- min-width[min-height] > flex container(優先級)
max-width[height]
- Flex-basis < max-width[height] 值
- Flex-basis < max-width[height](優先級)--通過flex-grow伸展開。
總結:
- width:auto、width:非auto、flex、min-width[min-height]、max-width[height]和flex-basis兩兩比較時取最大值
- width:非auto 和 flex-basis(優先級)同時設置時,width:非auto < flex-basis(優先級)
伸展和坍塌
這要分兩種情況,換行或者不換行。
1. 如果 flex-wrap: nowrap; 即不換行。
1. Flex-item總和 < flex-box時
- flex-grow計算流程是:
- 可用空間 = flexbox-content - 每個item-size的總和
- 單位分配空間 = 可用空間 / grow
- 每個item延伸的尺寸 = 單位分配空間 * 對應的item grow
注意:flex-shrink 的計算流程和flex-grow的計算流程不同。
2. Flex-item總和 > flex-box時
- flex-shrink計算流程是:
- 加權和(flex-shrink) = flex-shrink * item-size
- 每個item的shrink比例 = 每個item的flex-shrink * item-size / 加權和
- 超出空間 = Flex-item(所有子項目之和) - flex-box(flex盒子尺寸)
- 每個item坍塌后的尺寸 = flex-basis - 超出空間 * 每個item的shrink比例
1. flex-wrap: wrap[wrap-reverse]; 即換行
items 都會先在主軸方向上的多條線上排列,每條線之間互不干擾
1. grow、max-width[height] 情況下 flex-grow 的計算流程
- 第一次分配
- 剩余空間 = flex-box - 統計帶max-width[height]屬性的item-size之和
- 有剩余空間則再分配
- 每個item最終尺寸 = item的flex-basis + 剩余空間*每個item的flex-grow / 所以的item的flex-grow之和
2. min-width[height] 情況下 flex-shrink 的計算流程
- 第一次坍塌
- 按正常的flex-shrink 的計算流程,計算出每個item坍塌后的尺寸
- item沒有坍塌的尺寸 = 帶min-width[height]屬性的item-size - item坍塌后的尺寸
- item最終尺寸 = 每個沒有帶min-width[height]屬性的item坍塌后的尺寸 - 每個item的flex-shrink(item沒有坍塌的尺寸 / item的flex-shrink之和)
隱藏屬性對 items-size 的影響
display: none、visibility: hidden、visibility: collapse和transform: scale;
- visibility: hidden; | visibility: collapse; | transform: scale;的flex-item content 依然被算進主軸尺寸
- display: none; CSS解析器不會對該item的空間進行計算