對元素CSS的display屬性設置flex或者inline-flex,那么這個元素就是彈性盒模型容器(flex container),其子元素就是彈性盒模型子元素(flex item)。在容器中,水平的主軸(main axis)和垂直的交叉軸(cross axis)撐起這個彈性盒模型,對於子級元素,單個元素的主軸空間稱為main size,占據的交叉空間稱為cross size。
一個彈性盒模型的屬性分為容器本身的屬性和容器子元素的屬性,盒子的屬性決定子元素的對齊、排版方式,相當於容器內的整體布局,子元素的屬性決定子元素的順序和分布情況,也就是對單獨的盒模型子元素進行調整。
一、容器相關屬性
1、flex-direction、flex-wrap和flex-flow
flex-flow(彈性流動配置)屬性的值由flex-direction(彈性方向)和flex-wrap(彈性空間換行)屬性組成,這一組值都是用於改變主軸設置的,而主軸的方向決定彈性布局的屬性值對盒模型子元素在空間內的分配方式。flex-direction屬性值默認為row(主軸方向為行的方向,水平方向),其子元素的排列方向為延主軸從左至右排列,除此之外還可以取row-reverse、column(主軸方向為列的方向,垂直方向)和column-reverse,分別表示從右往左,從上至下和從下到上。flex-wrap決定盒子的主軸的數量,默認情況下,容器內容會按照一排布置在容器內(主軸只有一條),當寬度不足時,所有的元素都將進行等比例壓縮,container的flex-wrap默認值就是對應的nowrap不換行,換行為wrap(按照子元素寬度的占比出現多條主軸),換行並反向排列為wrap-reverse。一個彈性盒子的默認排列方式如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container{ width: 302px; height: 302px; border:1px solid; display: flex;} .item{width: 100px; height: 100px} .item1-1{ background:red;} .item1-2{ background:orange;} .item1-3{ background:yellow;} .item1-4{ background:green;} .item1-5{ background:cyan;} .item1-6{ background:blue;} </style> </head> <body> <div class="container "> <div class="item item1-1">1</div> <div class="item item1-2">2</div> <div class="item item1-3">3</div> <div class="item item1-4">4</div> <div class="item item1-5">5</div> <div class="item item1-6">6</div> </div> </body> </html>
結果如下:
可以看到,本來寬度為100px的子級方塊寬度被壓縮,子級元素沒有換行,那么如果進行按列排列並且換行后反向排列的結果如何?
上述代碼加上樣式 .container{ flex-flow: column wrap-reverse; } 結果如下:

子元素位置在頁面上的分布,經過彈性盒模型屬性值設定之后,表現的位置並不與HTML順序一致,但實際上元素的位置並沒有發生改變。
2、容器主軸分布方式:justify-content屬性
前面提到的主軸和交叉軸的概念主要用於后面幾個屬性,如justifu-content,當主軸方向為水平或者垂直、正向或者反向會是效果呈現很大的變化。該屬性的值有有flex-start(排列到主軸方向頭部)、flex-end(排列到主軸方向尾部)、center(主軸中間)以及space-between(主軸方向等距離分配,且兩端與邊緣無間距)和space-around(主軸方向等距離分配,且兩端與邊緣也是等間距)。下面分別為space-between和space-around的展示效果。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .between,.around{ width: 302px; height: 102px;border:1px solid; display: flex; float: left; margin-left: 50px;} .between{ justify-content: space-between;} .around{ justify-content: space-around;} .item1-1{ background:red;} .item1-2{ background:orange;} .item1-3{ background:yellow;} .item1-4{ background:green;} .item1-5{ background:cyan;} .item1-6{ background:blue;} .item2{ width: 80px; height: 80px;} </style> </head> <body> <div class="container between"> <div class="item item1-1 item2">1</div> <div class="item item1-2 item2">2</div> <div class="item item1-3 item2">3</div> </div> <div class="container around"> <div class="item item1-4 item2">1</div> <div class="item item1-5 item2">2</div> <div class="item item1-6 item2">3</div> </div> </body> </html>
采用space-between和space-around的結果如下左右展示:

當主軸方向是垂直時{flex-direction: column;},上面的等間距分配也是在垂直方向上分配。
3、容器內交叉軸分布方式align-items和align-content
align-items是針對彈性盒子內只有一條主軸是,子元素在交叉軸上的分布,align-content是在盒模型有多條主軸時,元素在交叉軸上的分布,其分布方式對於每一個子元素適用。align-items的屬性值可以為flex-start、flex-end、center以及stretch(衍生,子元素的高度將全部填充為當前主軸的最高高度)和baseline(交叉軸為垂直方向時,元素會根據第一行文本的基礎線進行對齊),align-content的屬性值為flex-start、flex-end、center、stretch以及space-between和space-around。
使用align-items並且屬性值為baseline和使用align-content並且屬性值為space-around結果如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .align_items,.align_content{ width: 302px; height: 302px;border:1px solid; display: flex; float: left; margin-left: 50px;} .align_items{ align-items: baseline; } .align_content{ flex-wrap: wrap; align-content: space-around; justify-content: space-around;} .item1-1{ background:red;} .item1-2{ background:orange;} .item1-3{ background:yellow;} .item1-4{ background:green;} .item1-5{ background:cyan;} .item1-6{ background:blue;} .item3-1,.item3-2,.item3-3{ width: 100px; height: 80px;} .item3-3{ font-size: 50px; } .item3-1{ font-size: 24px;} .item4-1{ width: 200px; height: 80px;} .item4-2{ width: 30px; height: 50px;} .item4-3{ width: 280px; height: 100px;} .item4-4{ width: 80px; height: 30px;} .item4-5{ width: 40px; height: 100px;} .item4-5{ width: 120px; height: 60px;} </style> </head> <body> <div class="container align_items"> <div class="item1-1 item3-1">1</div> <div class="item1-2 item3-2">2</div> <div class="item1-3 item3-3">3</div> </div> <div class="container align_content"> <div class="item1-1 item4-1">1</div> <div class="item1-2 item4-2">2</div> <div class="item1-3 item4-3">3</div> <div class="item1-4 item4-4">4</div> <div class="item1-5 item4-5">5</div> <div class="item1-6 item4-6">6</div> </div> </body> </html>
結果如下:(便於觀察,為align-content屬性的盒子設置了延主軸方向保持子元素周圍間距相等,所以該盒子子元素四周間距應當相等,除設置高度影響外)

二、子元素的彈性盒模型屬性
彈性盒模型容器的屬性,決定了容器子元素在盒模型內的分布,一個屬性值改變的是所有元素的分布方式,而容器子元素也有彈性盒模型屬性可以設置,主要更改子元素本身的樣式,也會間接影響周圍元素。子元素彈性盒模型屬性比較簡單。
1、子元素的順序排列order屬性
子元素的順序可以采用order屬性進行設置,默認值為0,數值越小,元素的順序就越靠近主軸起點,當值相同是按照DOM順序排列。order引起位置的變化並不會改變DOM的位置。
2、子元素的flex屬性
這也是一個復合的屬性(類似flex-flow由flex-direction和flex-wrap組成),對於子元素設置flex屬性包括flex-grow,flex-shrink和flex-basis,分別代表子元素在彈性盒子內的放大比例,縮小比例和基本尺寸。flex-grow放大比例決定了元素在彈性盒子內存在剩余空間的分配情況,默認值為0,意思為就算還有剩余空間也不進行放大。flex-shrink縮小比例據定了彈性盒子溢出時的壓縮情況,默認值為1,即各元素等比例進行縮小,當值為0時,空間不足,該元素也不會進行縮小。flex-basis給與了元素的基本尺寸,元素被壓縮時不會比basis的值還要小,這樣可以滿足盒子在屏幕縮放的情況系自動換行並填充。例如盒模型內擁有3個子元素,設置彈性盒模型后還有剩余空間,分別設置flex-grow值為1,2,2,那么他們將會把剩余空間的1/5,2/5,2/5填充到自身元素的寬度內,本來設置元素寬度均為100px,那么經過擴充后寬度就不止100px了。
3、子元素的align-self屬性
調節彈性盒子的元素交叉軸對齊方式除了在容器采用align-items和align-conten屬性,還可以對子元素設置align-self屬性調整其交叉軸的位置,其屬性值可以為auto(默認值,表示繼承父元素的align-items屬性,沒有父元素時等同於stretch)、flex-start、flex-end、center以及stretch和baseline。
