1、簡介
Flexbox 子產品提供了一個有效的布局方式,即使不知道視窗大小或者未知元素情況下都可以智能的,靈活的調整和配置設定元素和空間兩者的關系。簡單來說就是,可以自動調整,計算元素在容器空間中的大小。
上圖是一個橫向的,文本流從左到右的彈性布局示意圖。這裡有幾個概念:
(1)彈性容器(Flex container),指一個聲明為 flex 或者 inline-flex 的元素,是所有 Flex items 的父元素。
(2)彈性項目(Flex item),指 flex 容器内的直接孩子元素;彈性容器中的直接文本項預設為彈性項目。
(3)主軸(main axis)和側軸(cross axis),類似于二維中的 X 和 Y 軸,主軸由屬性 flex-direction 來定義,與主軸垂直的軸則是側軸。
2、使用
要使用彈性布局,需要定義一個彈性容器,通過聲明 display 屬性為 flex 或 inline-flex 來将此元素定義為彈性容器。即将父元素定義為彈性容器。(IE 系列浏覽器中 IE10+ 支援)
<style type="text/css">
ul{
display: flex;
}
li{
width: 100px;
height: 100px;
background-color: #ccc;
margin: 8px;
list-style-type: none;
}
</style>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
上圖可看出,子元素并排顯示,預設情況下
li
是垂直顯示,此時使用
display:flex
使其并排顯示,從左到右,就像你使用了
float
一樣。此時,
ul
為 flex 容器,而其子元素
li
就變成了 flex 項目。
3、Flex 容器屬性
Flex 容器屬性有:
- flex-direction 定義排列方向
- row 預設值,主軸為水準方向,從左到右排列
- row-reverse 主軸為水準方向,從右到左排列
- column 主軸為垂直方向,從上到下排列
- column-reverse 主軸為垂直方向,從下到上排列
- flex-wrap 定義是否新行顯示,以及新行的排列方向
- nowrap 預設值,顯示在同一行,不換行
- wrap 一行顯示不了時使用新行顯示
- wrap-reverse 同 wrap ,但是從下向上顯示
- flex-flow 是 flex-direction 和 flex-wrap 的簡寫方式
- 使用方法 flex-flow: <’flex-direction’> || <’flex-wrap’>
- 預設值為:row nowrap
- justify-content 定義彈性項目在主軸上的對齊方式
- flex-start 預設值,從起始位置對齊,通常為左對齊
- flex-end 從結束位置對齊,通常為右對齊
- center 居中對齊
- space-between 兩端對齊,平均間隔
- space-around 每個元素都有相等的外邊距,相鄰元素外邊距不會疊加
- align-items 定義彈性項目在側軸上的對齊方式
- stretch 預設值,彈性項目在沒指定高度或者高度為 auto 的情況下,則高度會占滿空間
- flex-start 側軸起點開始對齊(頂部對齊)
- flex-end 從側軸結束位置對齊(底部對齊)
- center 相對側軸居中對齊(居中對齊)
- baseline 與基線對齊
- align-content 定義多行在側軸的對齊方式,當隻有一行是,不起作用
- stretch 預設值,各行會伸展以占滿整個縱軸空間
- flex-start 對齊到縱軸起點
- flex-end 對齊到縱軸終點
- center 相對縱軸中間對齊
- space-between 各行相對縱軸兩端對齊,各行間隔相等
- space-around 各行都有相等的外邊距,各行的外邊距不會疊加
4、flex 項目屬性
Flex 項目屬性有:
- flex-grow 數字,定義彈性項目的放大比例,預設0
- flex-shrink 數字,定義彈性項目的縮小比例,預設1, 值 0 表示不縮小
- flex-basis 數字,定義彈性項目的預設尺寸,預設 auto(根據内容大小計算)
-
flex 是 flex-grow flex-shrink flex-basis 的縮寫,預設值為 0 1 auto
flex:正數 與 flex: 正數 1 0 相同
- align-self 定義此彈性項目本身的對齊方式,會覆寫彈性容器 align-items 定義的對齊方式
- auto 從彈性容器繼承
- stretch 彈性項目在沒指定高度或高度為 auto 的情況下,則高度會占滿空間
- flex-start 側軸起點開始對齊
- flex-end 從側軸結束位置對齊
- center 相對側軸居中對齊
- baseline 與基線對齊
- order 數字,定義彈性項目的顯示順序,數字越小越靠前
(1)相對和絕對的 Flex 項目
flex 項目屬性中的 flex 屬性值隻設定 flex-grow 和 flex-shrink 值 或 隻有 flex-grow 值,這就是絕對 flex 項目,此時, flex-basis 預設為 0。隻有設定了 flex-basis 就是一個相對 flex 項目
li{/* 這是一個絕對的 flex 項目*/
flex: 1 1; /* flex-basis 預設為 0*/
}
li{/* 這是一個相對的 flex 項目*/
flex-basis: 100px; /* 隻設定了 flex-basis */
}
相對 flex 項目内的間距是根據它的内容大小來計算。而絕對 flex 項目中,隻根據 flex 屬性來計算,而不是内容。
相對 flex 項目,此時,各個 flex 項目大小不一緻,都根據自身的内容計算寬度。
<style type="text/css">
ul {
display: flex; /*觸發彈性盒*/
list-style: none;
}
li {
flex: auto; /*記住這與 flex: 1 1 auto; 相同*/
border: 2px solid red;
margin: 2em;
}
</style>
<ul>
<li>
This is just some random text to buttress the point being explained.
Some more random text to buttress the point being explained.
</li>
<li>This is just a shorter random text.</li>
</ul>
絕對 flex 項目,此時各個 flex 項目大小一緻,都是根據 flex 屬性計算寬度。
li {
flex: 1; /*記住這與 flex: 1 1 0; 相同*/
border: 2px solid red;
margin: 2em;
}
(2)margin: auto 對齊
當在 flex 項目上使用 margin: auto 時,值為 auto 的方向(左、右或兩者都是)會占據所有空間。
<style type="text/css">
ul {
display: flex; /*觸發彈性盒*/
list-style: none;
border: 2px solid red;
}
li {
flex: 0 0 auto;
border: 2px solid black;
}
</style>
<ul>
<li>Area A</li>
<li>Area B</li>
</ul>
上圖可以看到,沒加 margin: auto 時,右邊會有一些多餘空間。
下面給 A 區域加上 margin-right: auto
li:nth-child(1){
margin-right: auto;
}
上圖可以看到,加 margin:auto 後,A 區域的 margin 将剩餘空間占滿
注意:當在一個 flex 項目上使用自動外邊距(margin: auto)時,justify-content 屬性将不起作用。
5、注意
(1)margin: auto 對齊
當在 flex 項目上使用 margin: auto 時,值為 auto 的方向(左、右或兩者都是)會占據所有空間。
(2)設定 flex-direction: column 後主、側軸交換。
未設定 flex-direction: column 時,主軸方向是從左到右,側軸方向是從上到下。
設定 flex-direction: column 時,主軸方向從上到下,側軸方向從右到左。
下面是預設情況:
<style type="text/css">
ul {
display: flex; /*觸發彈性盒*/
list-style: none;
border: 2px solid red;
}
li {
flex: 0 0 auto;
border: 2px solid black;
}
</style>
<ul>
<li>Area A</li>
<li>Area B</li>
</ul>
設定設定 flex-direction: column
ul {
display: flex; /*觸發彈性盒*/
list-style: none;
border: 2px solid red;
flex-direction: column;
}
此時,可以看到,項目的寬度填滿了空間。如果使用 flex-basis 來使項目變窄時,将發現,此時的 flex-basis 影響的不在是寬度,而是高度,因為主、側軸發生了變化。
li {
flex: 0 0 auto;
border: 2px solid black;
flex-basis: 50px;
}
此時,要想正确的減少 flex 項目的寬度,應該使用 width 屬性。
li {
flex: 0 0 auto;
border: 2px solid black;
width: 50px;
}
此時,要将 flex 項目居中,應該使用 align-items: center 屬性。即主、縱軸交換,則原來影響主軸的屬性,改變後将影響側軸的屬性。原來影響側軸的屬性,改變後将影響主軸的屬性。
ul {
display: flex; /*觸發彈性盒*/
list-style: none;
border: 2px solid red;
flex-direction: column;
align-items: center;
}
參考了解 Flexbox:你需要知道的一切