摘要:分配空間原理影響布局分配空間的屬性有三個,分別是和。伸縮項目擴(kuò)展寬度項目容器寬度項目寬度或項目設(shè)置的總和對應(yīng)的比例拉伸后伸縮項目寬度原伸縮項目寬度擴(kuò)展寬度我們來計算一下上面栗子中第一個伸縮項目拉伸后的寬度。
在項目中,我們還會大量使用到flexbox的新舊屬性,但大多數(shù)人一般只會寫新屬性,舊屬性交由autoprefixer處理,但其實完成同樣功能的新舊屬性表現(xiàn)形式卻不盡相同。還有部分人只使用“萬能”的flex:number屬性為伸縮項目分配空間,但有些特殊情景卻無法滿足,此文為此梳理了flexbox的新舊屬性區(qū)別和分配空間的原理,為大家用flexbox布局的項目通通渠。
Flexbox兼容性PC端的兼容性
移動端的兼容性
如上圖,為了兼容IE10-11和Android4.3-,UC,我們?nèi)孕枰褂肍lexbox的舊屬性。
Flexbox新舊屬性Flexbox的新屬性提供了很多舊版本沒有的功能,但是目前Android4.x和UC仍有一定市場占有率需要兼容,因此目前只使用新舊屬性都有的功能。
能實現(xiàn)相同功能的Flexbox新舊屬性如下表:
但想象是美好的,現(xiàn)實是殘酷的,新舊屬性里有那么幾個頑固分子并不能乖乖的表現(xiàn)的一樣,總有那么一點(diǎn)不同。
下面我們來看看是哪些新舊屬性有不同:
相同點(diǎn):改變主軸方向和伸縮項目的排列順序;在ltr下伸縮項目從右到左排列。
不同點(diǎn):
flex-direction:row-reverse:第一個伸縮項目向主軸起點(diǎn)對齊
box-orient:horizontal;box-direction:reverse:最后一個伸縮項目向主軸終點(diǎn)對齊
相同點(diǎn):改變主軸方向和伸縮項目的排列順序;在ltr下伸縮項目從下到上排列。
不同點(diǎn):
flex-direction:column-reverse:第一個伸縮項目向主軸起點(diǎn)對齊。
box-orient:vertical;box-direction:reverse:最后一個伸縮項目向主軸終點(diǎn)對齊。
相同點(diǎn):定義伸縮項目顯示順序。
不同點(diǎn):
oreder:integer:默認(rèn)值為0;可以為負(fù)值。
box-ordinal-group:integer:默認(rèn)值為1;取值大于1。
相同點(diǎn):定義伸縮項目的擴(kuò)展因素。
不同點(diǎn):box-flex:number同時定義了伸縮項目的縮小因素。
相同點(diǎn):定義伸縮項目的縮小因素。
不同點(diǎn):box-flex:number同時定義了伸縮項目的擴(kuò)展因素。
影響Flexbox布局分配空間的屬性有三個,分別是flex-grow、flex-shrink和flex-basis。
flex-grow:當(dāng)伸縮項目在主軸方向的總寬度 < 伸縮容器,伸縮項目根據(jù)擴(kuò)展因素分配伸縮容器的剩余空間。
flex-shrink:當(dāng)伸縮項目在主軸方向的總寬度 > 伸縮容器,伸縮項目根據(jù)縮小因素分配總寬度超出伸縮容器的空間。
flex-basis:伸縮基礎(chǔ),在進(jìn)行計算剩余空間或超出空間前,給伸縮項目重新設(shè)置一個寬度,然后再計算。
我們先來看看如何計算計算拉伸后的伸縮項目寬度,先簡單明了的給個公式,再通過栗子來驗證。
伸縮項目擴(kuò)展寬度 = (項目容器寬度 - 項目寬度或項目設(shè)置的flex-basis總和) * 對應(yīng)的flex-grow比例
拉伸后伸縮項目寬度 = 原伸縮項目寬度 + 擴(kuò)展寬度
.flexbox-wrap{ width:550px; display: flex; } .flexbox-item{ &:nth-child(1){ width:60px; } &:nth-child(2){ width:70px; } &:nth-child(3){ flex-basis:80px; } &:nth-child(4){ flex-basis:90px; } &:nth-child(5){ flex-basis:100px; } } @for $i from 1 through 5 { .flexbox-item:nth-child(#{$i}){ flex-grow: $i; background-color: rgba(35 * (6-$i), 20 * $i, 35 * $i,1); } }
我們來計算一下上面栗子中第一個伸縮項目拉伸后的寬度。
對應(yīng)著公式一步步計算:
// 項目容器寬度 container = 550 // 項目寬度或項目設(shè)置的flex-basis總和 itemSum = 60 + 70 + 80 + 90 + 100 = 400 // 第一個伸縮項目對應(yīng)的flex-grow比例 flexRatio = 1 / ( 1 + 2 + 3 + 4 + 5 ) = 1/15 // 第一個伸縮項目擴(kuò)展寬度 extendWidth = ( 550 - 400 ) * 1/15 = 10 // 第一個伸縮項目拉伸后的寬度 itemWidth = 60 + 10 = 70
計算后得到第一個伸縮項目拉伸后的寬度是70px,我們通過chrome上的盒子模型來看看是否正確
chrome計算的結(jié)果和我們計算的結(jié)果是一致的。
根據(jù)拉伸的計算公式是不是很容易就能推演出壓縮的計算公式呢?
伸縮項目縮小寬度 = (項目寬度或項目設(shè)置的flex-basis總和 - 項目容器寬度) * 對應(yīng)的flex-shrink比例
壓縮后伸縮項目寬度 = 原伸縮項目寬度 - 縮小寬度
繼續(xù)用個栗子來驗證公式是否正確
.flexbox-wrap{ width:250px; display: flex; } .flexbox-item{ &:nth-child(1){ width:60px; } &:nth-child(2){ width:70px; } &:nth-child(3){ flex-basis:80px; } &:nth-child(4){ flex-basis:90px; } &:nth-child(5){ flex-basis:100px; } } @for $i from 1 through 5 { .flexbox-item:nth-child(#{$i}){ flex-shrink: $i; background-color: rgba(35 * (6-$i), 20 * $i, 35 * $i,1); } }
我們來計算一下上面栗子中第一個伸縮項目壓縮后的寬度。
對應(yīng)著公式一步步計算:
// 項目容器寬度 container = 250 // 項目寬度或項目設(shè)置的flex-basis總和 itemSum = 60 + 70 + 80 + 90 + 100 = 400 // 第一個伸縮項目對應(yīng)的flex-shrink比例 flexRatio = 1 / ( 1 + 2 + 3 + 4 + 5 ) = 1/15 // 第一個伸縮項目縮小寬度 extendWidth = ( 400 - 250 ) * 1/15 = 10 // 第一個伸縮項目壓縮后的寬度 itemWidth = 60 - 10 = 50
計算后得到第一個伸縮項目壓縮后的寬度是50px,我們通過chrome上的盒子模型來看看是否正確
chrome計算的結(jié)果和我們計算的結(jié)果不一樣。
伸縮項目壓縮的計算方式和拉伸的不一樣,是因為壓縮會有極端情況,我們把第一個伸縮項目的flex-shrink修改為10,此時縮小寬度為( 400 - 250 ) * ( 10 / 24) = 62.5,縮小的寬度比原寬度要大,計算的壓縮后的寬度變成了負(fù)數(shù)。
為了避免這種極端情況,計算縮小比例是要考慮伸縮項目的原寬度。
正確的公式是這樣的
伸縮項目縮小寬度 = (項目寬度或項目設(shè)置的flex-basis總和 - 項目容器寬度) (對應(yīng)的flex-shrink 項目寬度或項目設(shè)置的flex-basis比例)
壓縮后伸縮項目寬度 = 原伸縮項目寬度 - 縮小寬度
對應(yīng)著公式一步步計算:
// 項目容器寬度 container = 250 // 項目寬度或項目設(shè)置的flex-basis總和 itemSum = 60 + 70 + 80 + 90 + 100 = 400 // 第一個伸縮項目對應(yīng)的flex-shrink比例 flexRatio = (1*60) / (1*60+2*70+3*80+4*90+5*100) = 6/130 // 第一個伸縮項目縮小寬度 extendWidth = ( 400 - 250 ) * 6/130 ≈ 6.922 // 第一個伸縮項目壓縮后的寬度 itemWidth = 60 - 6.922 = 53.078
計算后得到第一個伸縮項目壓縮后的寬度是53.078px,和chrome上的盒子模型是一樣的。
Flexbox屬性縮寫陷阱上面介紹的flex-grow、flex-shrink和flex-basis有一個縮寫的寫法flex。
flex: flex-grow [flex-shrink] [flex-basis]
flex各種縮寫的值
flex: initial == flex: 0 1 auto
flex: none == flex: 0 0 auto
flex: auto == flex: 1 1 auto
flex: number == flex: number 1 0%
在實際項目中,會直接寫使用縮寫的flex來給伸縮項目分配空間,但是使用縮寫屬性會留下一些陷阱,導(dǎo)致表現(xiàn)的結(jié)果不盡如人意。
分別使用flex和flex-grow來把伸縮項目拉伸填滿容器,看看表現(xiàn)的差異。
首先看看使用flex-grow拉伸伸縮項目的效果
.flexbox-wrap{ width:550px; display: flex; } .flexbox-item{ flex-grow:1; &:nth-child(1){ width:60px; } &:nth-child(2){ width:70px; } &:nth-child(3){ width:80px; } &:nth-child(4){ width:90px; } &:nth-child(5){ width:100px; } } @for $i from 1 through 5 { .flexbox-item:nth-child(#{$i}){ background-color: rgba(35 * (6-$i), 20 * $i, 35 * $i,1); } }
每個伸縮項目在原寬度上拉伸相同的寬度
通過上面的計算拉伸后的伸縮項目寬度,可以計算第一個伸縮項目拉伸后的寬度
// 項目容器寬度 container = 550 // 項目寬度或項目設(shè)置的flex-basis總和 itemSum = 60 + 70 + 80 + 90 + 100 = 400 // 第一個伸縮項目對應(yīng)的flex-grow比例 flexRatio = 1 / ( 1 + 1 + 1 + 1 + 1 ) = 1/5 // 第一個伸縮項目擴(kuò)展寬度 extendWidth = ( 550 - 400 ) * 1/5 = 30 // 第一個伸縮項目拉伸后的寬度 itemWidth = 60 + 30 = 90
然后我們把flex-grow:1替換成flex:1,下面是表現(xiàn)的效果,伸縮項目拉伸后的寬度變成一樣了。
從chrome的盒子模型可看到伸縮項目拉伸后寬度變成了110px,伸縮容器等分了容器的寬度。
flex:1展開后是flex:1 1 0%,flex-grow:1相當(dāng)于flex:1 1 auto,兩者的區(qū)別在于flex-basis的值不同。flex:1為項目寬度重新設(shè)置了寬度為0,所以可分配空間為整個容器,從公式計算上可以更直觀理解:
// 項目容器寬度 container = 550 // 項目寬度或項目設(shè)置的flex-basis總和 itemSum = 0 + 0 + 0 + 0 + 0 = 0 // 第一個伸縮項目對應(yīng)的flex-grow比例 flexRatio = 1 / ( 1 + 1 + 1 + 1 + 1 ) = 1/5 // 第一個伸縮項目擴(kuò)展寬度 extendWidth = ( 550 - 0 ) * 1/5 = 110 // 第一個伸縮項目拉伸后的寬度 itemWidth = 0 + 110 = 110需要注意的Flexbox特性 無效屬性
column-*在伸縮容器無效
float和clear在伸縮項目無效
vertical-align在伸縮項目無效
::first-line and ::first-letter在伸縮容器無效
伸縮容器中的非空字符文本節(jié)點(diǎn)也是伸縮項目margin折疊1 2 我是個假文本 3 4 5
伸縮容器和伸縮項目的margin不會折疊
伸縮項目間的margin不會折疊
舊版Flexbox的BUG伸縮項目為行內(nèi)元素要加display:block;或display:flex
歡迎關(guān)注:Leechikit
原文鏈接:segmentfault.com到此本文結(jié)束,歡迎提問和指正。
寫原創(chuàng)文章不易,若本文對你有幫助,請點(diǎn)贊、推薦和關(guān)注作者支持。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/112178.html
摘要:然而學(xué)習(xí)布局,你只要學(xué)習(xí)幾個手機(jī)端頁面自適應(yīng)解決方案布局進(jìn)階版附源碼示例前端掘金一年前筆者寫了一篇手機(jī)端頁面自適應(yīng)解決方案布局,意外受到很多朋友的關(guān)注和喜歡。 十分鐘學(xué)會 Fiddler - 后端 - 掘金一.Fiddler介紹 Fiddler是一個http抓包改包工具,fiddle英文中有欺騙、偽造之意,與wireshark相比它更輕量級,上手簡單,因為只能抓http和https數(shù)據(jù)...
摘要:音樂團(tuán)隊分享數(shù)據(jù)綁定運(yùn)行機(jī)制分析一個項目搞定所有主流架構(gòu)單元測試一個項目搞定所有主流架構(gòu)系列的第二個項目。代碼開源,展示了的用法,以及如何使用進(jìn)行測試,還有用框架對的進(jìn)行單元測試。 Android 常用三方框架的學(xué)習(xí) Android 常用三方框架的學(xué)習(xí) likfe/eventbus3-intellij-plugin AS 最新可用 eventbus3 插件,歡迎品嘗 簡單的 MVP 模...
摘要:柵格系統(tǒng)用于處理頁面多終端適配的問題。它表示抓取對象以后拖放到另一個位置。目前,它是標(biāo)準(zhǔn)的一部分。精簡高效的命名準(zhǔn)則方法這篇文章發(fā)布于年月日,星期日,,歸類于相關(guān)。但是不會受到包含塊的限制,可能會溢出。 一勞永逸的搞定 flex 布局 尋根溯源話布局 一切都始于這樣一個問題:怎樣通過 CSS 簡單而優(yōu)雅的實現(xiàn)水平、垂直同時居中。記得剛開始學(xué)習(xí) CSS 的時候,看到 float 屬性不由...
閱讀 2118·2021-11-24 10:28
閱讀 1143·2021-10-12 10:12
閱讀 3350·2021-09-22 15:21
閱讀 691·2021-08-30 09:44
閱讀 1907·2021-07-23 11:20
閱讀 1155·2019-08-30 15:56
閱讀 1767·2019-08-30 15:44
閱讀 1490·2019-08-30 13:55