1.背景
傳統的布局方案基於盒狀模型,依賴display + position + float 的方式實現,靈活性較差,對於那些特殊的布局非常不方便.
2009年,W3C提出了一種新的方案--Flex布局.
2.什么是Flex布局?
Flex是Flexible Box的縮寫,意為"彈性布局",用來為盒模型提供最大的靈活性,以便我們能夠簡便、完整、響應式的實現多種網頁布局.
任何一個容器都可以指定為Flex布局,行內元素也可以設置為Flex布局
<div class="box"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
.box { display: flex; /*行內元素設置為 inline-flex*/ } .box .item { width: 100px; height: 100px; background-color: red; margin-left: 10px; }
注意,設為 Flex 布局以后,子元素的float
、clear
和vertical-align
屬性將失效。
3.基本概念
采用 Flex 布局的元素,稱為 Flex 容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為 Flex 項目(flex item),簡稱"項目"。
容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。
Flex項目默認沿主軸排列。單個項目占據的主軸空間叫做main size,占據的交叉軸空間叫做cross size。
Flex屬性分為兩部分,一部分作用於容器稱容器屬性,另一部分作用於項目稱為項目屬性。下面我們就分別來介紹它們。
4.Flex容器的屬性
4.1 flex-direction屬性
flex-direction屬性決定主軸的方向(即項目排列的方向)
基本語法:
.box { flex-direction: row | row-reverse | column | column-reverse; }
說明:
(1)row表示從左向右排列
(2)row-reverse表示從右向左排列
(3)column表示從上向下排列
(4)column-reverse表示從下向上排列
4.2 flex-warp屬性
默認情況下,Flex項目都排在一條軸線上.我們可以通過對flix-warp的屬性的設置,讓Flex項目是否換行
基本語法:
.box { flex-wrap: nowrap | wrap | wrap-reverse; }
說明:
(1)nowrap:所有項目單行排列
(2)warp:所有項目多行排列,按照從上到下的順序
(3)warp-reverse:所有項目多行排列,按照從上到下的順序
4.3 flex-flow
flex-flow
屬性是flex-direction
屬性和flex-wrap
屬性的簡寫形式,用來設置項目的排列方式。默認值為row nowrap
基本語法:
.box { flex-flow: <flex-direction> || <flex-wrap>; }
例如我給容器設置 flex-flow: row wrap-reverse;就是主軸從左向右,從下到上多行排列
4.4 justify-content
justify-content
屬性定義了項目在主軸上的對齊方式及額外空間的分配方式。
基本語法:
.box { justify-content: flex-start | flex-end | center | space-between | space-around; }
說明:
(1)flex-start: 左對齊
(2)flex-end:右對齊
(3)center:居中
(4)space-between:項目均勻分布,項目第一項在主軸起點,最后一項在主軸終點
(5)space-around:項目兩側的間隔相等,項目之間的距離是兩側距離的2倍
(6)space-evenly:項目均勻分布
4.5 align-items
align-items
屬性定義項目在交叉軸上的對齊方式。
基本語法:
.box { align-items: stretch | flex-start | flex-end | center | baseline; }
說明:
(1)stretch:交叉軸方向拉伸顯示
(2)flex-start:項目按交叉軸起點線對齊
(3)flex-end:項目按交叉軸終點線對齊
(4)center:交叉軸方向項目中間對齊
(5)baseline:交叉軸方向按第一行文字基線對齊
4.6 align-content
align-content
屬性定義了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。
基本語法:
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
說明:
(1)flex-start:與交叉軸的起點對齊
(2)flex-end:與交叉軸的終點對齊
(3)center:與交叉軸的中點對齊
(4)space-between: 與交叉軸兩端對齊,軸線之間平均分布
(5)space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍
(6)stretch:軸線占滿整個交叉軸。
5.Flex項目屬性
5.1 order
默認情況下,Flex項目是按照在代碼中出現的先后順序排列的。然而order
屬性可以控制項目在容器中的先后順序。
基本語法:
.item { order: <integer>; }
假如有四個盒子按照1,2,3,4排列,我想讓2號盒子排在第一位,那么就把2號盒子的order的值寫成最小即可,order可以設置負值
5.2 flex-grow
flex-grow
屬性定義項目的放大比例,默認為0
,即如果存在剩余空間,也不放大。
基本語法:
.item { flex-grow: <number>; /* default 0 */ }
如果所有項目的flex-grow屬性都為1,則它們將等分剩余空間(如果有的話)
如果一個項目的flex-grow屬性為2,其他項目都為1,則前者占據的剩余空間將比其他項多一倍。
5.3 flex-shrink
flex-shrink
屬性定義了項目的縮小比例,默認為1,即如果空間不足,該項目將縮小。
基本語法:
.item { flex-shrink: <number>; /* default 1 */ }
如果所有項目的flex-shrink
屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink
屬性為0,其他項目都為1,則空間不足時,前者不縮小。
負值對該屬性無效
5.4 flex-basis
flex-basis
屬性定義項目在分配額外空間之前的默認尺寸。屬性值可以是長度(20%,10rem等)或者關鍵字auto
。它的默認值為auto,即項目的本來大小。
基本語法:
.item { flex-basis: <length> | auto; /* 默認 auto */ }
說明:
(1) flex-basis:auto
(2)flex-basis:3em
(3) flex-basis:30%
5.5 flex
flex
屬性是flex-grow
, flex-shrink
和 flex-basis
的簡寫,默認值為0 1 auto
。后兩個屬性可選。
基本語法:
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
5.6 align-self
align-self
屬性定義項目的對齊方式,他允許每個項目有不一樣的對其方式,可覆蓋align-items屬性。默認值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch。 除了auto,其他都與align-items屬性完全一致。
基本語法:
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
6.Flex實例
6.1 網格布局
(1) 最簡單的網格布局,就是平均分布。在容器里面平均分配空間,需要設置項目的自動縮放。
html代碼:
<div class="box">
<span class="item">***</span>
<span class="item">***</span>
</div>
css代碼:
.box { display: flex; width: 550px; } .box .item { flex: 1; background-color: red; margin-right: 10px; border-radius: 5px; font-size: 20px; text-align: center; }
(2) 百分比布局
設置某個網格的寬度為固定百分比,其它網格平均分配剩余的空間
html代碼
<div class="box14"> <span class="item14">1/2</span> <span class="item14">1/4</span> <span class="item14">auto</span> <span class="item14">auto</span> </div>
css代碼
.box14 { display: flex; width: 550px; margin-bottom: 10px; } .box14 .item14 { flex: 1; background-color: red; margin-right: 10px; border-radius: 5px; font-size: 20px; text-align: center; } .box14 .item14:first-child { flex: 0 0 50%; } .box14 .item14:nth-child(2){ flex: 0 0 25%; }
6.2 聖杯布局
聖杯布局指的是一種最常見的網站布局。頁面從上到下,分成三個部分:頭部(header),軀干(body),尾部(footer)。其中軀干又水平分成三欄,從左到右為:導航、主欄、副欄。
html代碼:
<div class="box15"> <header>header</header> <div class="connent"> <div class="main">main</div> <div class="left">left</div> <div class="right">right</div> </div> <footer>footer</footer> </div>
*最外層盒子應該是body標簽,為了演示畫了一個600*600的盒子
css代碼:
.box15 { width: 600px; height: 600px; font-size: 30px; color: #fff; text-align: center; display: flex; flex-direction: column; } .box15 header,.box15 footer { height: 50px; background-color: red; } .box15 .connent { display: flex; flex: 1; } .box15 .connent .main { flex: 0 0 400px; background-color: pink; } .box15 .connent .left, .box15 .connent .right{ flex: 0 0 100px; background-color: #ccc; } .box15 .connent .left { order: -1; }
6.3 篩子的布局
(1)
html代碼:
<div class="box16"> <span class="item"></span> </div>
css代碼:
.box16 { width: 100px; height: 100px; background-color: #ccc; border-radius: 5px; display: flex; justify-content: center; align-items: center; } .box16 .item { width: 15px; height: 15px; background-color: #000; border-radius: 50%; }
(2)
html代碼:
<div class="box17"> <span class="item"></span> <span class="item"></span> <span class="item"></span> </div>
css代碼:
.box17 {
width: 100px;
height: 100px;
background-color: #ccc;
border-radius: 5px;
display: flex;
}
.box17 .item { width: 15px; height: 15px; background-color: #000; border-radius: 50%; } .box17 .item:nth-child(2) { align-self: center; } .box17 .item:nth-child(3) { align-self: flex-end; }
6.4 九宮格效果
html代碼:
<div class="box18"> <span class="item"></span> <span class="item"></span> <span class="item"></span> <span class="item"></span> <span class="item"></span> <span class="item"></span> <span class="item"></span> <span class="item"></span> <span class="item"></span> </div>
css代碼
.box18 { width: 350px; display: flex; flex-wrap: wrap } .box18 .item { width: 100px; height: 100px; background-color: red; margin: 5px 5px; }
6.5 條件搜索
像是一些后台OA可能用到很多條件查詢並列在一起,如果布局的整齊些,可以用Flex布局
html代碼:
<div class="box19"> <div class="search"> <span>條件一</span> <select> <option value="1">請選擇</option> <option value="1">111</option> <option value="2">222</option> <option value="3">333</option> </select> </div> <div class="search"> <span>條件二</span> <select> <option value="1">請選擇</option> <option value="1">111</option> <option value="2">222</option> <option value="3">333</option> </select> </div> ....... ....... </div>
css代碼:
.box19 { display: flex; flex-wrap: wrap; } .box19 .search { width: 150px; display: flex; margin: 5px 20px 0 0; } .box19 .search span { font-size: 14px; color: #000; margin-right: 5px; } .box19 .search select { flex-grow: 1 }
以上所有的案例都放在了我的github中,克隆地址