css 的 flex 彈性佈局在平常開發中有着普遍的應用,其彈性伸縮的靈活性對響應式需求的開發提供了便利,柵格佈局,垂直居中等等設置flex佈局後,加上幾個屬性就能夠輕鬆實現。基本使用能夠參考阮老師的博客css
flex能夠當作一個容器,其中有一個主軸(main axis)和交叉軸(cross axis)做爲容器內容的排布基準。容器中的每一個子元素稱爲項目,這些項目都排列在主軸(main axis)上,每一個項目在主軸方向上佔用空間稱爲main size。咱們能夠經過設置項目的width屬性來指定main size的大小,也能夠經過flex屬性(flex-grow,flex-strink,flex-basic的結合)使main size大小成爲響應式。html
每一個項目上直接設置width大小,項目大小即爲width的值,這種方式不會讓寬度自適應,若是容器寬度大於或小於項目寬度總和,就會出現容器有大量留白或超出容器的狀況,爲了不這種狀況,一般會指定flex屬性來使項目寬度自適應從而佔滿整個容器。算法
指定flex-grow屬性,項目會自動擴張到和容器寬度一致佈局
計算相加每一個項目flex-grow得出總和爲T,並將容器寬度W均分紅W/T,每一個項目的寬度就是flex
main size = flex-grow * W / Tspa
演示地址3d
容器寬度先減去這些項目width或flex-basic的值,容器剩下的寬度會按flex-grow來計算並分配給全部項目。main size = flex-basic + (W - 每一個項目寬度) * flex-grow / Tcode
*注:flex-basic的優先級高於widthhtm
演示地址blog
項目寬度先按上面兩個算法計算出寬度,若是項目寬度大於了max-width,多餘的寬度會從新分配給沒有設置max-width屬性的項目。
計算法則
指定flex-strink屬性,項目寬度會自動收縮到和容器寬度一致。引用MND上的說法:
CSS flex-shrink 屬性指定了 flex 元素的收縮規則。flex 元素僅在默認寬度之和大於容器的時候纔會發生收縮,其收縮的大小是依據 flex-shrink 的值
其實這裏收縮和擴張的算法是不同的,收縮的大小不能直接用flex-strink來計算,以這段代碼爲例:
.flex-item1 { background-color: red; flex: 0 8 800px; } .flex-item2 { background-color: gray; flex: 0 4 400px; } .flex-item3 { background-color: antiquewhite; flex: 0 2 200px; } .flex-item4 { background-color: orange; flex: 0 1 100px; }
這裏能夠計算出項目的總寬度是 1500px 大於了容器寬度 1000px,按照MDN的說法,計算第一個項目的寬度應該是:800 - (1500 - 1000)*(8 / 15)= 533.33px
能夠看出項目的收縮大小並非經過flex-strink直接獲得的,要計算項目的收縮後的寬度,還須要用到flex-basic。以上面的代碼爲例,先要去計算項目的虛擬總寬度VS = 各項目flex-basic flex-strink 之和,再計算單個項目的佔比P = flex flex-strink / VS,最後計算項目應該減去的大小 = 真實超出部分 * P,
能夠計算出第一個項目的寬度爲:
先計算出項目收縮後的寬度,若是項目寬度大於了max-width,最終項目的大小會以max-width的值爲準,且多餘的寬度會分配給其餘項目;若是項目小於了min-width,最終項目的大小會以min-width爲準,且少分配的寬度會從其餘項目中減去。分配給其餘項目的這部分寬度要準守上面所寫的計算規則按佔比分配
先計算出項目收縮後的寬度,按照「多退少補」的方式來處理max-width和min-width的狀況,舉個例子:
.flex-item1 { background-color: red; flex: 0 4 400px; /* 240 */ min-width: 310px; } .flex-item2 { background-color: gray; flex: 0 2 400px; /* 320 */ max-width: 280px; } .flex-item3 { background-color: antiquewhite; flex: 0 4 200px; /* 120 */ max-width: 100px; } .flex-item4 { background-color: orange; flex: 0 2 200px; /* 160 */ } .flex-item5 { background-color: lightcoral; flex: 0 2 200px; /* 160 */ }
項目1收縮後的寬度是240px,min-width是300px,因此項目1就借走了60px須要從其餘項目中補上60px;項目2收縮後的寬度是320px,max-width是280px,因此項目2少了40px就退給其餘項目;項目3頁同理,120-100=20px,要退給其餘項目20px。來來回回發現,就這項目1借的寬度恰好能夠由項目2和項目3補上,互補以後兩清了,因而,項目4和項目5的寬度不受影響不變化。
項目的寬度超出了容器的寬度,超出部分的項目自動移動到到下一行去,在每一行中,項目的寬度計算都以flex-grow爲準
若是position的值使項目脫離文檔流,容器中的項目flex屬性就會失效,其餘的項目寬度按flex屬性自適應。
flex佈局中項目的自適應寬度(高度)經過flex-grow和flex-strink決定的,兩者都是將容器中剩餘或超出的寬度(高度)分配給各個項目,flex-grow是將剩餘寬度按flex-grow比分配給各個項目,flex-strink是根據各個項目本來寬度*flex-strink佔總虛擬寬度的比來分配項目應該減去的寬度。