可能大家在平時工作中都會用到一些框架比如Bootstrap
,iview
,Element-ui
等,這些UI框架都會有柵格系統,柵格系統已經能很好的滿足業務需求,所以可能對css3的彈性布局不是很感冒,有的用就行了,但是若不使用任何框架完成柵格怎么辦,豈不是麻爪了,學習一下彈性盒模型,了解其基礎用法,以及深入。
什么是彈性盒模型
采用Flex布局的元素,稱為Flex容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為 Flex 項目(flex item),簡稱"項目"。
使用彈性盒模型要給容器添加dispaly:flex;
屬性。

對Css熟悉的童鞋應該對盒模型都又一定的了解,彈性盒模型其本質上就是Box-model(盒子模型)的延伸,Box-model(盒子模型)定義了一個元素的盒模型,而Flexbox(彈性盒子)更進一步的去規范了這些盒模型之間彼此的相對關系。
彈性盒模型按照寬高分出了以下8點:
- 水平的主軸:main axis,垂直的縱軸:cross axis
- 縱軸的開始位置和邊框的交點:cross start
- 縱軸的結束位置和邊框的交點:cross end
- 主軸的開始位置和邊框的交點:main strat
- 主軸的結束位置和邊框的交點:main end
- 單個項目占據主軸的空間距離:main axis
- 單個項目占據縱軸的空間距離:cross axis

容器屬性
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
flex-direction
flex-direction屬性決定主軸的方向(即項目的排列方向)。
flex-direction屬性共有4個可選值
- row(默認值):以main start點為起始點,按照元素順序從左到右依次排列。
- row-reverse:以main end為起始點,按元素順序從右到左依次排列。
- column:以cross start為起始點,按元素順序從上到下依次排列。
- column-reverse:以cross end為起始點,按元素順序從下到上依次排列。

這里有一個很重要的區別:flex-direction:column並不是把塊從主軸移到交叉軸上排列,而是讓主軸自身從水平變成垂直。
另外 flex-direction 還有兩個選項值:row-reverse 和 column-reverse。

flex-wrap
默認情況下,項目都排在一條線(又稱"軸線")上。flex-wrap屬性定義,如果一條軸線排不下,如何換行。
flex-wrap屬性共有3個可選值
- nowrap(默認值):不換行。
- wrap:換行,第一行在上方,垂直縱軸以cross start為起始點,水平主軸以main start為起始點。
- wrap-reverse:換行,第一行在下方,垂直縱軸以cross end為起始點,水平主軸以main start為起始點。
flex-flow
flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,默認值為row nowrap。
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
這個很好理解,按照對應的可選屬性,填寫相對應的值即可。
例如:如果想讓其子元素以main end
為起始點並且換行的話。
.box {
display:flex;
flex-flow: row-reverse wrap;
}
justify-content
這定義了沿主軸的對齊。當主軸上的所有彈性項目都不靈活,或者靈活但已達到其最大尺寸時,它有助於分配剩余的額外空閑空間。當它們溢出線時,它還對物品的對齊施加一些控制。
justify-content屬性共有5個可選值,具體對齊方式與軸的方向有關。下面假設主軸為從左到右。
- flex-start(默認值):左對齊
- flex-end:右對齊
- center: 居中
- space-between:兩端對齊,項目之間的間隔都相等。
- space-around:每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。

align-items
align-items屬性定義項目在交叉軸上如何對齊。
align-items屬性共有5個可選值。具體的對齊方式與交叉軸的方向有關,下面假設交叉軸從上到下。
- flex-start:交叉軸的起點對齊。
- flex-end:交叉軸的終點對齊。
- center:交叉軸的中點對齊。
- baseline: 項目的第一行文字的基線對齊。
- stretch(默認值):如果項目未設置高度或設為auto,將占滿整個容器的高度。

文字基線

為了更清楚地闡明主軸和交叉軸的區別,下面我們來把 justify-content 和 align-items 合在一起,看看在 flex-direction 兩種值的作用下軸心有什么不一樣:

align-content
align-content屬性定義了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。
align-content屬性共有6個可選值。
- flex-start:與交叉軸的起點對齊。
- flex-end:與交叉軸的終點對齊。
- center:與交叉軸的中點對齊。
- space-between:與交叉軸兩端對齊,軸線之間的間隔平均分布。
- space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。
- stretch(默認值):軸線占滿整個交叉軸。
元素屬性
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
order
order屬性定義元素的排列順序。數值越小,排列越靠前,默認為0,可以使用負值。如果兩個元素的值相同,按照元素順序排列。
.item {
order: Number <integer>;
}
flex-grow
flex-grow屬性定義項目的放大比例,默認為0,即如果存在剩余空間,也不放大。
.item {
flex-grow: Number;
}
如果所有項目的flex-grow屬性都為1,則它們將等分剩余空間(如果有的話)。如果一個項目的flex-grow屬性為2,其他項目都為1,則前者占據的剩余空間將比其他項多一倍。
flex-shrink
flex-shrink屬性定義了項目的縮小比例,默認為1,即如果空間不足,該項目將縮小。
.item {
flex-shrink: Number;
}
如果所有項目的flex-shrink屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink屬性為0,其他項目都為1,則空間不足時,前者不縮小。
flex-basis
flex-basis屬性定義了在分配多余空間之前,項目占據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多余空間。它的默認值為auto,即項目的本來大小。
.container {
display:flex;
margin:50px auto 0px;
border: 1px solid red;
}
.container div {
width:100px;
height:100px;
background:pink;
margin:10px;
}
.container div:nth-child(1){
flex-basis:500px;
}
flex
flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫,默認值為0 1 auto。后兩個屬性可選。
.item {
flex:0 1 auto;
}
示例
.container {
display:flex;
margin:50px auto 0px;
border: 1px solid red;
}
.container div {
width:100px;
height:100px;
background:pink;
margin:10px;
}
.container div:nth-child(1){
flex:0 1 500px;
/* flex:1 0 500px; */
}
align-self
align-self屬性允許單個項目有與其他項目不一樣的對齊方式,可覆蓋align-items屬性。默認值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch。
示例
.container {
display:flex;
margin:50px auto 0px;
border: 1px solid red;
height:500px;
}
.container div {
width:100px;
height:100px;
background:pink;
margin:10px;
}
.container div:nth-child(1){
flex:0 1 500px;
align-self:flex-end;
}
.container div:nth-child(2){
flex:0 1 500px;
align-self:center;
}
下面將給兩個塊設置 align-self 屬性,其余的使用 align-items: center 和 flex-direction: row,來看看會是什么效果:

文章參考