筆者佈局時經常使用float,inline-block,對於flex,僅限於瞭解,卻一直沒有應用,遂決定抽出些時間學習一下,初次寫不免有漏洞,歡迎指正,後期不按期持續持續更新補充。css
我們首先從定義入手,flex究竟是個什麼東西呢?html
flex(flexible box):彈性佈局盒子模型,是W3C中新增的屬性,在寫以前demo練習中,明顯感受到flex,很是的便捷,短短几行代碼即可以達到佈局的效果,功能也很是的強大,既然吹得這麼厲害,俗話說無碼無真相,下面咱們一塊兒看一下神奇的flex吧!css3
首先要介紹下flex容器和flex項目,當某個元素採用flex佈局時,元素自動轉化爲Flex容器(flex-container),簡稱容器。元素內的子元素自動轉化爲容器內的項目,即Flex項目(flex items),簡稱項目。web
容器內默認有兩軸四點,兩軸分別爲縱向的主軸(main axis)和垂直主軸的交叉軸(cross axis),兩軸分別有各自的起點及中點,主軸起點爲main start,主軸的終點爲main end,交叉軸的起點稱爲cross start,終點稱爲cross end, 項目按照主軸或者交叉軸進行排布,項目沿着主軸方向的尺寸稱爲main size,項目沿着交叉軸方向的尺寸爲cross size,項目默認是按照主軸方向排布的,而且默認不折行,(以主軸排布)當項目寬度總和大於容器寬度時,各個項目寬度壓縮,即便設置固定寬度。瀏覽器
圖一 主軸-交叉軸示意圖(轉)ide
圖 二 主軸-交叉軸示意圖(轉)佈局
flex佈局中項目既能夠是行內元素(span)也能夠是塊級元素(div),項目爲行內元素時(見圖二),能夠對項目進行寬高的設置。此外,需注意使用flex容器內元素,即flex item的float,clear(清浮動)、vertical-align屬性將失效,position屬性能夠正常使用。學習
容器屬性包含有六個屬性:flex
1. flex-direction ui
2. flex-wrap
3. flex-flow
4. justify-content
5. align-items
6. align-content
flex-direction屬性爲項目排列方向,其中包含4個值。
1. row(默認項目排列方向) //容器主軸爲水平方向,其中項目自左向右按順序依次排布; (left-to-right)
2. row-reverse //容器主軸仍爲水平方向,其中項目自右向左依次排布;(right-to-left)
3. column //容器主軸爲垂直方向,項目自上而下排布;(top-to-bottom)
4. column-reverse //容器主軸爲垂直方向,項目自下而上排布;(bottom-to-top)
圖 二 row屬性值演示 圖 三 row-reverse屬性值演示
圖 四 column屬性值演示 圖 五 column-reverse屬性值演示
四幅圖分別對應flex-direction屬性的4個值,(demo信息:容器尺寸爲寬500px,高300px,每一個項目爲直徑100px的圓)圖二,圖三容器主軸爲水平方向演示,當項目總寬度大於容器寬度時項目寬度被壓縮,容器主軸爲垂直方向時,同理。項目總寬度/高度小於容器時,按照設置寬高沿着主軸排布。
圖四,圖五不難看出並不符合,咱們所說的項目總高度大於容器高度,項目被均勻壓縮狀況即圖二,圖三。這是由於咱們設置了line-height: 100px,在flex佈局中行高的影響並無被消除,致使項目並無被壓縮在容器中,設置行高後,項目累計高度大於容器部分的內容,在容器以外顯示,因爲設置了over-flow:hidden;因此在圖四圖五中,沒有顯示,仔細看不難發現圖四中的三弟圓顯示不完成,圖五中的三弟同理。因此在flex佈局中要當心使用行號;
flex佈局中行高和高度同時使用結果分析:
1)只設置行高:項目總行高小於容器高度時,項目按照垂直軸方向在容器內排列,當項目總行高大於容器高度時,大於容器高度項目溢出容器。
2)只設置高度:項目總高度小於容器高度時,項目按照垂直軸方向在容器內排列,當項目總高度大於容器高度時候,項目在容器中均勻排列,項目總高度最大值爲容器高度,不隨高度增長無限增長,項目不會溢出容器。
3)行高高度同時設置:項目行高及高度總值均小於容器高度時,按高度排列,行高不影響span高度,只改變內容位置。項目總高度及總行高均大於容器高度時,項目溢出容器,見圖四圖五;
flex-wrap屬性爲當總項目寬度超過容器寬度時候是否換行及換行方式,其中包含3個值。(以主軸水平爲例)
1. nowrap //默認屬性不換行,各個項目在容器內被壓縮; 2. wrap //項目總寬度超過容器時進行換行;
3. wrap-reverse //超出部分自下而上,沿主軸方向排列;
圖 六 flex-wrap屬性值演示
flex-flow屬性值爲flex-direction || flex-wrap兩種屬性的縮寫,默認值爲
row || nowrap
。
1 .box { 2 flex-flow: row wrap-reverse; 3 }
flex-flow屬性值爲沿主軸對齊方式,其中包含5種屬性值;(主軸爲水平軸爲例)
1. flex-start //項目以主軸起點對齊;(左對齊) 2. flex-end //項目以主軸終點對齊;(右對齊)
3. center //項目在主軸居中對齊; 4. space-between //項目以主軸起點終點爲起始點,中間等分對齊; 5. space-around //項目等分對齊,首尾項目距離邊框之和爲中間項目間距一半;
圖 七 justify-content屬性值演示
justify-content屬性值space-around中關於結論「首個及末尾項目距離邊框距離爲中間項目間距一半」驗證。
下面咱們有請圓圈家族中的四兄弟,驗證過程演示以下:首先選取前三個項目,圖八中的第一幅圖,其中容器寬度爲500px,圓形直徑爲100px,能夠推斷出,項目間距約等於66.66px,根據咱們的結論首末項目距離邊框距離應爲33.33px,在下面的第二幅圖中加入了四弟,而且設置了它的定位屬性,將left值設置爲33.33px,變有了咱們第三幅圖的結果,四弟將三弟覆蓋。
圖 八 space-around項目與border距離驗證
flex-flow屬性值爲沿交叉軸對齊方式,其中包含5種屬性值;(交叉軸爲垂直方向爲例)
1. flex-start //項目以交叉軸起點對齊;(上對齊) 2. flex-end //項目以交叉軸終點對齊;(下對齊) 3. center //項目在交叉中居中對齊; 4. baseline //項目沿着其中第一行文字基線對齊; 5. stretch //項目未設置交叉軸方向具體尺寸時(本例子爲高度),項目該尺寸佔滿整個容器;
(stretch有換行時,例如項目爲兩行,項目高度都爲容器高度1/2)
圖 九 align-items屬性值演示
align-content屬性值爲多行項目時沿交叉軸對齊方式,項目爲單行時,屬性值無效應使用align-items,其中包含6種屬性值;(交叉軸爲垂直方向爲例)
1 flex-start //多行項目以交叉軸起點對齊;(上對齊) 2 flex-end //多行項目以交叉軸終點對齊;(下對齊) 3 center //項目在交叉軸中間居中對齊; 4 space-between //首末行項目分別位於交叉軸起點終點,中間行等分,進行對齊; 5 space-around //項目等分對齊,首末行距離邊框爲中間項目間距的一半; 6 stretch //未設置高度時,項目佔滿整個容器,有多行時,等分容器高度;
圖 十 align-content部分屬性值演示(1-3)
圖 十一 align-content部分屬性值演示(4-6)
項目屬性包含有六個屬性:
1. order 2. flex-grow 3. flex-shrink 4. flex-basis 5. flex 6. align-self
order屬性能夠用來定義項目的順序,order的值越小,項目在主排列中的順序越靠前,全部項目默認值爲0;
圖 十二 order屬性值演示
flex-grow
屬性爲項目的放大比例,規定了項目在各自佔用多少剩餘可用空間大小,屬性值爲數字沒有單位,負數(Negative numbers)是無效的,默認爲0
,此時項目size爲自身尺寸,不會方法。
若是全部項目flex-grow設置爲1,容器中剩餘空間將被等分給項目,若其中有一個項目的value值爲2,該項目佔據的空間,則爲其它項目的2倍。
If all items have flex-grow
set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least)。(轉)
圖 十三 flex-grow屬性值演示(各項目flex-grow: 1;)
圖 十四 flex-grow屬性值演示(大哥flex-grow: 2;其他爲1)
容器寬度爲500px,圓設置直徑爲100px,不難算出剩餘寬度爲100px,圖十三中圓形各自寬度爲125px,圖十四中大哥寬度爲140px,其他寬度爲120px,從而不難看出,flex-grow屬性值是將容器剩餘空間寬度按flex-grow值得比例分配。
flex-shrink
屬性爲項目的縮小比例,只有在項目寬度之和大於容器的時候纔會依據flex-shrink值發生收縮,默認值(default value)爲1,負數(negative numbers)無效,默認狀況下全部項目均可以被縮放,可是若是設置爲0,該項目將維持最初設置尺寸,不被壓縮。
圖 十五 flex-shrink屬性值演示(default:1)
圖十五中的七兄弟被flex-shrink均爲默認值縮放後的效果,不難算出每一個寬度爲500/7=71.43px,項目寬度按照容器寬度壓縮值相等。雖然咱們知道當flex-shrink值不一樣時也會被壓縮,那麼是根據什麼進行的壓縮呢?壓縮值又是多少呢?
圖 十六 flex-shrink屬性值演示(首個項目flex-shrink:2)
從圖十七中咱們能夠看出兄弟中大哥寬度爲500px,其他六兄弟寬度爲75px,flex-shrink屬性和flex-grow屬性定義正好相反,是將項目size之和超出容器部分尺寸根據flex-shrink值按比例進行壓縮,以沿寬度方向壓縮爲例進行分析:
圓設置寬度爲100px,項目個數爲7個,總寬度應爲700px,實際容器寬度爲500px,超出容器部分爲200px,壓縮因子(flex-shrink值)分別爲2:1:1:1:1:1:1;
壓縮值分別爲:
大哥 200/(2+1+1+1+1+1+1)*2=50px; 二弟 200/(2+1+1+1+1+1+1)*1=25px; 三弟 200/(2+1+1+1+1+1+1)*1=25px; 四弟 200/(2+1+1+1+1+1+1)*1=25px; 五弟 200/(2+1+1+1+1+1+1)*1=25px; 六弟 200/(2+1+1+1+1+1+1)*1=25px; 七弟 200/(2+1+1+1+1+1+1)*1=25px;
項目實際寬度分別爲50px,75px,75px,75px,75px,75px,75px。注意:寬度計算時邊框包含在內。
圖 十七 壓縮後項目寬度值
flex-basis
屬性定義了在項目按照縮放因子(shrink factor)或者放大因子(grow factor)分配剩餘空間以前,項目的最初尺寸,能夠和寬度和高度屬性取相同的值(例如200px),flex-basis設置的長度值優先級高於width,不會被width,height覆蓋。它的默認值爲auto,即項目原來的size。
圖 十七 flex-basis屬性值演示
flex屬性是flex-grow,flex-shrink,flex-basis屬性的簡寫,默認值0 1 auto, 第二個和第三個參數是可選的(flex-shrink,flex-basis)。這個屬性還能夠設置爲auto(1 1 auto)和none(0 0 auto),建議優先W3C推薦使用這種簡短屬性,而不是單獨的三個分離的屬性,瀏覽器會本身解析剩餘部分。
圖 十七 flex屬性值取值規律
有如下三種狀況:
1)當flex爲單一非負數字值(沒法取到負值,被禁止),對flex-grow進行設置flex-shrink值爲1,flex-basis值爲0%;
2)當flex爲兩位非負數字時,分別對flex-grow和flex-shrink進行設置,flex-basis值仍爲0%;
3)當flex單一非負長度或者百分比,對flex-basis值進行設置;
align-self屬性值定義某個項目在容器內與交叉軸的對其方式,項目設置的align-self值能夠覆蓋align-items的值,默認值爲auto,表明繼承父元素的align-items屬性值,該屬性有6個屬性值,除了auto其他屬性值和容器屬性的align-items值相同。(詳見2.五、align-items屬性)
1. auto 2. flex-start
3. flex-end 4. center 5. baseline 6. stretch
圖 十八 align-self屬性值實例(center)
參考文獻:
【0】Flex 佈局教程:語法篇 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
【1】Flex 佈局教程:實例篇 http://www.ruanyifeng.com/blog/2015/07/flex-examples.html
【2】彈性佈局各類坑爹兼容 https://www.cnblogs.com/yangjie-space/p/4856109.html
【3】A Complete Guide to Flexbox https://css-tricks.com/snippets/css/a-guide-to-flexbox/
【4】A Visual Guide to CSS3 Properties https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties