CSS之深入理解 flex 布局以及计算
生活随笔
收集整理的這篇文章主要介紹了
CSS之深入理解 flex 布局以及计算
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
起因:對于Flex布局,閱讀了大漠老師和其他老師寫的文章后,我還是不太理解Flexbox是如何彈性的計算子級項目的大小以及一些其他細節。在大漠老師的幫助下,我去查閱Flexbox 的 W3C 規范文檔
1. 對于flex盒模型的設計期望:
- 在任何流動的方向上(包括上下左右)都能進行良好的布局
- 可以以逆序 或者 以任意順序排列布局
- 可以線性的沿著主軸一字排開 或者 沿著側軸換行排列
- 可以彈性的在任意的容器中伸縮大小(今天重點研究的主題)
- 可以使子元素們在容器主軸方向上 或者 在容器側軸方向上 進行對齊
- 可以動態的 沿著主軸方向 伸縮子級的尺寸,與此同時保證父級側軸方向上的尺寸
2. 主軸和側軸
首先每一根軸都包括 三個東西:維度、方向、尺寸
- 所謂的維度實際上就是意思就是子元素 橫著排還是豎著排(x 軸 或 y 軸)
- 方向 即排列子元素的順序 順序還是逆序
- 尺寸 即width[height] : 每一個子元素在主軸方向所占的位置的總和 如果主軸是水平的,那么尺寸就是父元素內所有item的outerWidth總和,如果主軸是垂直的,那么尺寸就是父元素的outerHeight
主軸是依靠 flex-direction 和 所有子元素在主軸方向上的item-size的總和確定的,flex-direction這個屬性可以控制子元素的排列方向和排列順序
側軸是依靠 flex-wrap 和 所有子元素在主軸方向上的item-size的總和確定的,flex-wrap 可以控制子元素 在側軸方向上的排列方式以及順序
而關于不同種類不同情況下的 item-size 我們會在下面討論,現在您可以簡單將它理解為width[height]
為了方便 flex-direction + flex-wrap 合并成了一個屬性 flex-flow
通過這個簡單而復雜的屬性,我們就能夠控制所有子元素的水平和垂直方向,逆序排列和順序,換行和不換行
主側軸的切換十分簡單,當主軸設定的時候,它的垂直面,就默認被設定成了側軸
這條CSS屬性能夠告訴我們那些信息?
- 子元素是橫著排列的,主軸是水平的橫軸,側軸是豎直的縱軸
- 子元素是逆序并沿著主軸排列的,從右到左
- 子元素是換行的
- 子元素是逆序并沿著側軸排列的,從下到上
3. FFC (flex formatting context)
Flexbox 布局新定義了格式化上下文,類似 BFC(block formatting context)。有多類似呢? 就是除了布局和一些細節不同以外的一切規則都和 BFC 是相同的
例如,設置了 display: flex; 或 display: inline-flex的元素,和BFC一樣,不會被浮動的元素遮蓋,不會垂直外邊距坍塌等等
而對于設置了 display: inline-flex 的盒子來說,我們可以類比 display: inline-box;行理解。即 一個被行列化后的 Flexbox。它不會獨占一行,但是可以設置寬和高
4. 與BFC的細微區別
- Flexbox 不支持 ::first-line 和 ::first-letter 這兩種偽元素
- vertical-align 對 Flexbox 中的子元素 是沒有效果的
- float 和 clear 屬性對 Flexbox 中的子元素是沒有效果的,也不會使子元素脫離文檔流(但是對Flexbox本身是有效果的!)
- 多欄布局(column-*) 在 Flexbox 中也是失效的,就是說我們不能使用多欄布局在Flexbox 排列其下的子元素(魚和熊掌不可得兼嘛)
- Flexbox 下的子元素不會繼承父級容器的寬
5. flex item(flex 子元素)
CSS解析器會把定義了 display: flex 和 display: inline-flex 的 Flexbox 下的子元素整體裝進一個看不見的盒子(這個盒子也就是 flex item )里,我們通過排列這些盒子來達到排序、布局、 伸縮的目的
規范中把這種盒子稱為 flex item,而子元素中包括了標簽節點以及文本節點。標簽節點很容易理解,需要注意的是文本節點(Flexbox的所有子元素自動成為容器成員,稱為Flex項目(flex item),簡稱”項目”。 )
默認情況下,flex 會將連續的文本節點裝進 flex-item 之中,使文本可以和標簽節點一起排序和定位
值得注意的是,空格也是文本節點,所以 white-space 會影響Flexbox 中的布局
使用white-space屬性之后,flexbox會將空格也算成字符,包裹進flex item內
6. flex-item-size 如何計算的
item-size(尺寸)為主軸方向上item的content再加上自身的margin 、 border 和 padding 就是這個item的尺寸
6.1 flex-basis 的優先級比 width[height]: 非auto; 高
如果子元素沒有內容和默認固定寬高,且設置了flex-basis。flex-item content以flex-basis來決定,無論width[height] 設置了多少,(可理解為 flex-basis 比 width[height]: 非auto 的優先級高)
這里div的內容為空,則使用flex-basis設定的寬高
如果子元素沒有內容和默認固定寬高,那flex-basis的優先級比width[height]高,無論width[height]設置多少,flex-item content都以flex-basis來決定
6.2 元素存在默認寬高
如果子元素有默認固定寬高(例如input標簽在頁面中會有一個默認的寬和高)、并且設置了flex-basis,那么它的content以固定寬高為min-width/height,如果flex-basis 超過了固定寬高,那么flex-basis則成為其 content,如果flex-basis比固定寬高小,那么以固定寬高為 content
6.3 元素存在 min-width[height] 或者 max-width[height]
如果flex-item有min-width[min-height]的限制,那么flex-item content按照min-width值為下限,如果flex-basis的值大于min-width[min-height]那么flex-item content以flex-basis計算
如果flex-basis的值小于min-width[min-height]那么flex-item content以min-width[min-height]計算
顯然,1號item設置的600px大于300px所以沿用了600px的寬,而2號的100px寬小于300px,所以使用的是300px的min-width
如果 min-width[min-height] 的值已經超出了容器的尺寸,那么即使設置了 flex-shrink。 CSS解析器也不會進行將這個item的 content 縮放,而是堅持保留它的min-width[min-height]
可見如果Flexbox設置的min-width超出了 flex container 的范圍,也不會對其進行壓縮
反之,如果設置了 max-width[height] 的值,那么設置flex-basis無法超過這個值,對于 flex-grow 也僅僅只會增長到 max-width[height] 這個上限,而并不會超過它
7. width[height]: auto 優先級等于 flex-basis
前面提到,如果給item同時設置了 width[height] 和 flex-basis 的話。flex-item content以flex-basis來決定。但是實際上默認的 width[height]: auto優先級是等于 flex-basis 的
CSS解析器對比兩者的值,兩者誰大取誰作為item的基本尺寸,如果一個item沒有內容,那么auto可能為空,所以flex-item content就會以flex-basis來決定
但是如果item有了內容,且內容撐開的尺寸比flex-basis大,那么flex-item content就會根據width[height]: auto來決定,且無法被縮放。反之,如果比flex-basis小,flex-item content就會以flex-basis來決定
width: auto時當內容長度比 flex-basis 大,則 flex-item content以內容長度來決定,且無法shrink
如果 flex-basis 的長度大于文字內容長度,那么flex-item content以 flex-basis 來決定
同時設置了flex-basis: 800px; 和 width: 1px; flex-item content以 flex-basis 來決定,可以發生shrink
注意2號盒子我設置了 flex-shrink: 1; 1號盒子和3號盒子我設置了 flex-shrink: 0; 意思就是我將所有的需要shrink的空間都壓到了2號盒子上,總共的需要 shrink的空間為 0 * 600 + 1 * 20 + 0 * 100 = -20;而2號盒子只有20的空間,理應被完全shrink變為0,但是值得注意的是2號盒子并沒有被完全 shrink,還保留了一個文字的距離
除此之外,overflow: hidden; 也會影響
文字長度在 600px; 小于 flex-basis: 700px,所以flex-item content以flex-basis來決定,可以shrink
8. 隱藏屬性對 items-size 的影響
我針對了 display: none; visibility: hidden; visibility: collapse; transform: scale; 等屬性對 items 進行測試
結果如下:
- 如果設置了 visibility: hidden; | visibility: collapse; | transform: scale;的flex-item content 依然被算進主軸尺寸,CSS 解析器依然會根據他們的 flex-grow | flex-shrink 將可用空間 或者 負可用空間 分配給他們
- 如果設置了display: none; CSS解析器不會對該item的空間進行計算,也不會對其grow空間
9. 關于position: absolute 對item影響
position: absolute 也是適用 Flexbox 中的子元素的,并且設置了position: absolute屬性的子元素,也會受到 Flexbox 排列的影響
設置了absolute 的子元素重疊在了一起,但是依然會受到 align-items: center; 的影響而居中。對于 Flexbox 本身來說,設置了position: absolute并不會對其下的子元素產生任何影響
我們重點看 Flexbox 下的子元素設置了 absolute 后有什么結果
根據我做的實驗,我得到了如下的結論:
flexbox 下設置了absolute的子元素的位置受3個方面的影響:
- flexbox 流下面的 justify-content(主軸上對齊方式) 和 align-items(交叉軸上對齊方式)
- 單個子元素的 top、left、right、bottom
- 單個子元素的 margin
設置了absolute 的 item 不會影響布局,如圖其中1 2 3 4 5 號是設置了absolute的item,而 6 7 8 9號是沒有設置absolute的item Flexbox 我設置了 justify-content: center; 和 align-items: center; 每一個item我都給了 margin: 20px
#
總結
以上是生活随笔為你收集整理的CSS之深入理解 flex 布局以及计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏策划学习(一)游戏研发基础
- 下一篇: CSS之Flexbox制作CSS布局易如