Flex布局
一、什么是Flex布局?
Flex是Flexible Box的縮寫,顧名思義為“彈性布局”,用來為盒裝模型提供最大的靈活性。
任何一個容器都可以指定為Flex 布局。
1
2
3
|
.box{
display
:flex;
}
|
行內元素也可以使用Flex布局。
1
2
3
|
.box{
display
:inline-flex;
}
|
webkit內核的瀏覽器,必需加上-webkit前綴
1
2
3
4
|
.box{
display
:-webkit-flex;
display
:flex;
}
|
需要注意的是,設為flex布局以后,子元素的float、clear和vertical-align屬性將失效
二、基本概念
采用Flex布局的元素,稱為Flex容器(flex container),簡稱“容器”。它的所有子元素自動成為容器成員,成為flex項目(flex item),簡稱“項目”。
容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框 的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。
項目默認沿主軸排列。單個項目占據的主軸空間叫做main size,占據的交叉軸空間叫做cross size。
三、容器的屬性
以下6個屬性設置在容器上。
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
3.1flex-direction屬性
flex-direction屬性決定主軸的方向(即項目的排列方向)。
.box{ flex-direction:row | row-reverse | column | column-reverse; }
它可能有四個值
- row(默認值):主軸為水平方向,起點在左端
- row-reverse:主軸為水平方向,起點在右端
- column:主軸為垂直方向,起點在上沿
- column-reverse:主軸為垂直方向,起點在下沿
3.2flex-wrap屬性
默認情況下,項目都排在一條線(又稱“軸線”)上。flex-wrap屬性定義,如果一條軸線 排不下,如何換行?
.box{ flex-wrap: nowrap | wrap | wrap-reverse; }
它可能去三個值。
(1)nowrap(默認):不換行
(2)wrap:換行,第一行在上方
(3)wrap-reverse:換行,在第一行的下方
3.3 flex-flow
flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,默認 row nowrap。
.box{ flex-flow:<flex-direction> || <flex-wrap>; }
3.4 justify-content屬性
justify-content屬性定義了項目在主軸上的對齊方式
.box{ justify-content:flex-start | flex-end | center | space-between |space-around; }
它可能取5個值,具體對齊方式與軸的方向有關。下面假設主軸為從左到右。
- flex-start(默認值):左對齊
- flex-end:右對齊
- center:居中
- space-between:兩端對齊,項目之間的間隔都相等
- space-around:每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。
3.5 align-items屬性
align-items屬性定義項目在交叉軸上如何對齊。
.box{ align-items:flex-start | flex-end | center |baseline | stretch; }
它可能取5個值。具體的對齊方式與交叉軸的方向有關,下面假設交叉軸從上之下。
- flex-start:交叉軸的起點對齊
- flex-end:交叉軸的終點對齊
- center:交叉軸的中點對齊
- baseline:項目的第一行文字的基線對齊。
- stretch(默認值):如果項目未設置高度或設為auto,將占滿整個容器的高度。
3.6 align-content屬性
align-content屬性定義了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。
.box{ align-content:flex-start | flex-end | center | spance-between | space-around |stretch; }
該屬性可能取6個值。
- flex-start:與交叉軸的起點對齊。
- flex-end:與交叉軸的終點對齊。
- center:與交叉軸的中點對齊。
- space-between:與交叉軸兩端對齊,軸線之間的間隔平均分布。
- space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。
- stretch(默認值):軸線占滿整個交叉軸。
四、項目的屬性
一下6個屬性設置在項目上。
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
4.1 order屬性
order屬性定義項目的排列順序。數值越小,排列越靠前,默認為0.
.item{ order:<integer>; }
4.2 flex-grow屬性
flex-grow屬性定義項目的放大比例,默認值為0,即如果存在剩余空間,也不放大。
.item{ flex-grow:<number>;/* default 0*/ }
如果所有項目的flex-grow屬性都為1,則它們將等分剩余空間(如果有的話)。如果一個項目的flex-grow屬性為2,其他項目為1,則牽着占據的剩余空間將比其他項多一倍
4.3 flex-shrink屬性
flex-shrink屬性定義了項目的縮小比例,默認為1,即如果空間不足,改項目將縮小。
.item{ flex-shrink:<number>;/* default 1 */ }
如果所有項目的flex-shrink屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink屬性為0,其他項目都為1,則空間不足時,前者不縮小。
負值對該屬性無效。
4.4 flex-basis屬性
flex-basis屬性定義了在分配多余空間之前,項目占據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多余空間。它的默認值為auto,即項目的本來大小。
.item{ flex-basis:<length> | auto ; /*default auto*/ }
它可以設為跟width或height屬性一樣的值(比如350px),則項目將占據固定空間。
4.5 flex屬性
flex屬性是flex-grow,flex-shrink和flex-basis的簡寫,默認值為0 1 auto。后面兩個屬性可選
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
改屬性有兩個快捷值:auto(1 1 auto)和none(0 0 auto).
建議優先使用這個屬性,而不是單獨寫三個分離的屬性,因為瀏覽器會推算相關值
4.6 align-self屬性
align-self屬性允許單個項目有與其他項目不一樣的對齊方式,可覆蓋align-items屬性。默認值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,等同於stretch。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
該屬性可能取6個值,除了auto,其他都與align-items屬性完全一致。
幾個案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>flex布局</title> </head> <body> <p>flex布局1-適合導航欄(可任意添加個數,不需要改變css代碼)</p> <div class="ul"> <div class="li"><a href="" class="t">衣服</a></div> <div class="li"><a href="" class="t">褲子</a></div> <div class="li"><a href="" class="t">內衣</a></div> <div class="li"><a href="" class="t">帽子</a></div> </div> <style> .ul{ display: flex;} .li{flex:1;text-align: center; background: #666;color:#fff; margin:1px;} .li2{flex:2;text-align: center;color:#fff;} .t{border-radius: 50%;background: #cc9999; height:40px;width:40px;display: inline-block;line-height: 40px;} </style> <p>flex布局2-左圖右文字的樣式</p> <div class="demo1"> <div class="left"></div> <div class="right"> <p>Iphone7 PLUS XXXXXXXXXX</p> <span>總人數99</span> <span>剩余人數33</span> <div class="btn">立即參與</div> </div> </div> <style> .demo1{display: flex;/*設置為flex布局*/justify-content: space-around;} .demo1 > div{ flex: none;} .left{width: 200px;height: 200px;background: #d4cdcd;} .right{width: 380px;height: 200px;} </style> <p>flex布局3-垂直居中對齊</p> <div class="demo2"> <div class="inner"> <p>這是一個測試這是一個測試這是一個測試這是一個測試這是一個測試</p> </div> </div> <style> .demo2{ width: 100%;height: 300px;border: 1px solid purple;display: flex;/*設置為flex布局*/justify-content: center; /*水平居中*/ align-items: center; /*垂直居中*/} .inner{ width: 160px;font-size: 26px;border: 1px solid red;} </style> <p>flex布局4-多列</p> <div class="demo4"> <div class="left4" style="width:40px;height:40px;background: darkgoldenrod"></div> <div class="center4"> <p>description</p> <p>description</p> <p>description</p> <span>description</span> </div> <div class="btn4">確認</div> <div class="btn4">取消</div> </div> <style> .demo4{width: 100%;height: 150px; border: 1px solid #b7b2b7;margin: 30px auto;padding-top: 17px;display: flex;/*設置為flex布局*/ justify-content: space-around;} .demo4 > div{ flex: none;} </style> <p>flex布局5-多列</p> <div class="demo5"> <div class="item item1">1/4</div> <div class="item item2">auto</div> <div class="item item3">1/4</div> <div class="item item4">1/4</div> </div> <style> .demo5{display: flex;} .item{flex: 1;background: #ccffcc;margin: 2px;height:30px;text-align: center;line-height: 30px;} .item2{flex: 0 0 50%;}.item4{flex: 0 0 20%;} </style> <p>flex布局6-聖杯布局</p> <div class="demo6"> <div class="header" style="height:40px;line-height: 40px;text-align: center;background: cyan;">頭部</div> <div class="body"> <div class="left" style="height:200px;line-height: 200px;text-align: center;background: red; color:#fff;">left</div> <div class="center" style="height:200px;line-height: 200px;text-align: center;background: #999; color:#fff;">center</div> <div class="right" style="height:200px;line-height: 200px;text-align: center;background: red; color:#fff;">right</div> </div> <div class="footer" style="height:40px;line-height: 40px;text-align: center;background: #ccff99;">底部</div> </div> <style> .demo6{display: flex; flex-direction: column;} .demo6 div{flex: 1;}.body{ display: flex;} .header,.footer,.left,.right{flex: 0 0 20%!important;} </style> <p>flex布局7-底部布局</p> <div class="demo7" style="height:300px;border:1px solid #666;"> <div class="main7" style="text-align: center;">這是主要內容</div> <div class="footer7" style="height:40px;text-align: center;background: chartreuse;line-height: 40px;">這是底部</div> </div> <style> .demo7{display: flex;flex-direction: column;}.main7{flex: 1;} .footer7{width: 100%;height: 120px;} </style> <p>flex布局8-流式布局</p> <div class="demo8"> <div class="item8"></div> <div class="item8"></div> <div class="item8"></div> <div class="item8"></div> <div class="item8"></div> <div class="item8"></div> <div class="item8"></div> <div class="item8"></div> </div> <style> .demo8{width: 258px;height: 300px;display: flex;flex-wrap: wrap;align-content: flex-start;background: #cc9999;} .item8{flex: 0 0 33.333333%;height: 80px;border:1px solid #514c81;box-sizing: border-box;background: #ccff99;} </style> <style> .table .box {position: relative; width: 120px; height: 90px; text-align: center; line-height: 90px; background: #2F4056; font-size: 14px; color: #fff;} .table .box::before { content: ""; position: absolute; } .table .arr-l::before { top: 30px; left: -10px; border-top: 10px solid transparent; border-bottom: 10px solid transparent; border-right: 10px solid #2F4056; } .table .arr-l2::before { top: 30px; left: -10px; border-bottom: 10px solid transparent; border-right: 10px solid #2F4056; } .table .arr-r::before { top: 30px; left: 120px; border-top: 10px solid transparent; border-bottom: 10px solid transparent; border-left: 10px solid #2F4056; } .table .arr-r2::before { top: 30px; left: 120px; border-top: 3px solid transparent; border-bottom: 12px solid transparent; border-left: 12px solid #2F4056; } .table .arr-b::before { top: 90px; left: 60px; border-left: 10px solid transparent; border-right: 10px solid transparent; border-top: 10px solid #2F4056; } .table .arr-t::before { top: -10px; left: 50px; border-left: 10px solid transparent; border-right: 10px solid transparent; border-bottom: 10px solid #2F4056; } </style> <table class="table table-bordered"> <tr> <td><div class="box arr-l">arr-l</div></td> <td><div class="box arr-l2">arr-l2</div></td> <td><div class="box arr-r">arr-r</div></td> <td><div class="box arr-r2">arr-r2</div></td> <td><div class="box arr-t">arr-t</div></td> <td><div class="box arr-b">arr-b</div></td> </tr> </table> </body> </html>