flex佈局是繼標準流佈局、浮動佈局、定位佈局後的第四種佈局方式。這種方式可以非常優雅的實現子元素居中或均勻分佈,甚至可以隨着窗口縮放自動適應。 flex佈局在瀏覽器中存在一定的兼容性。但是在小程序中,是完全兼容 flex佈局的,並且微信官方也是推薦使用 flex佈局的。下面就來詳細的講下 flex佈局。
一個小例子:
看以下代碼:
<view class='outter'>
<view class='inner'>1</view>
<view class='inner'>2</view>
</view>
.outter{
display: flex;
justify-content: space-between;
width: 300px;
height: 200px;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
}
最後的效果圖:
基本概念:
1. 彈性容器:
包含着彈性項目的父元素。通過設置 display 屬性的值爲 flex 或 inline-flex 來定義彈性容器。
2. 彈性項目(Flex item):
彈性容器的每個子元素都稱爲彈性項目。彈性容器直接包含的文本將被包覆成匿名彈性項目。也可以稱爲子容器。
3. 軸(Axis):
每個彈性框佈局包含兩個軸。彈性項目沿其依次排列的那根軸稱爲主軸(main axis)。垂直於主軸的那根軸稱爲側軸(cross axis)。
4. 方向(Direction):
可以通過 flex-direction來確定主軸和側軸的方向。
設置在主軸上的排列方式:
默認情況下,主軸的方向是從左到右。在主軸方向上,可以通過 justify-content屬性來設置他們的排列方式。排列方式有以下幾種:
1. flex-start:項目靠近父盒子的左側。默認採用的就是這種排列方式。示例圖如下:
2. flex-end:項目靠近父盒子的右側。
3. center:所有項目會挨在一起在父盒子的中間位置。
4. space-around:項目沿主軸均勻分佈,位於首尾兩端的子容器到父容器的距離是子容器間距的一半。
5. space-between:項目沿主軸均勻分佈,位於首尾兩端的子容器與父容器緊緊挨着。
6. space-evenly:項目在主軸上均勻分佈,收尾兩端的自容器到父容器的距離跟自容器間的間距是一樣的。
設置在側軸上的排列方式:
默認情況下,側軸的方向是從上到下。在側軸方向上,可以通過 align-items屬性來設置他們的排列方式。排列方式有以下幾種:
1. flex-start:起始端對齊。默認就是這種對齊方式。
2. flex-end:末尾段對齊。
3. center:中間對齊。
4. stretch:如果項目沒有設置高度。那麼子容器沿交叉軸方向的尺寸拉伸至與父容器一致。比如我們將 .inner的高度屬性去掉,代碼如下:
.outter .inner{
background: gray;
width: 100px;
/* height: 100px; */
border: 1px solid #ccc;
}
效果圖爲:
5. baseline:基線對齊,這裏的 baseline 默認是指首行文字,所有子容器向基線對齊,交叉軸起點到元素基線
距離最大的子容器將會與交叉軸起始端相切以確定基線。比如我們把代碼改成如下:
<view class='outter'>
<view class='inner'>
<view style='margin-top:10px;background:#eee;'>hello</view>
</view>
<view class='inner'>2</view>
</view>
然後 wxss文件爲:
.outter{
display: flex;
align-items: baseline;
width: 300px;
height: 200px;
background: pink;
}
.outter .inner{...}
那麼效果圖爲:
更換主軸和側軸方向
主軸默認的方向是從左到右,側軸的方向默認是從上到下,當然也可以進行修改。可以通過 flex-direction進行修改。可以修改的參數爲以下:
1. row:默認屬性。從左到右。
2. row-reverse:從右到左。
3. column:從上到下。
4. column-reverse:從下到上。
換行
默認情況下,元素個數如果超過一定數量,那麼在一行當中就排列不下。此時 flex默認的處理方式是壓縮元素,使其能在一行中排列下來。比如以下代碼:
<view class='outter'>
<view class='inner'>1</view>
<view class='inner'>2</view>
<view class='inner'>3</view>
<view class='inner'>4</view>
</view>
.outter{
display: flex;
width: 300px;
height: 200px;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
border: 1px solid #ccc;
}
那麼會把這四個元素擠壓在一行中。即使給元素設置了寬度也沒有用的。效果圖如下:
可以通過 flex-wrap來改變排列的方式。可以設置的屬性如下:
1. nowrap:不換行。默認的。
2. wrap:換行。
3. wrap-reverse:換行,但是第一行會在下面。
align-content屬性
在排列中,如果有多行,那麼這個屬性是設置多行之間的排列方式。可以通過 align-content屬性來確定排列的方
式。可以設置以下值。
1. flex-start:從上往下排列。示例代碼如下:
.outter{
display: flex;
flex-wrap: wrap;
align-content: flex-start;
width: 300px;
height: 300px;
background: pink;
}
2. flex-end:末尾段對齊。效果圖如下:
3. center:中點對齊。效果圖如下:
4. space-between:與交叉軸兩端對齊,軸線之間的間隔平均分佈。效果圖如下:
5. space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。效果圖如下:
6. stretch:默認方式,如果沒有給元素設置高度,那麼會佔滿整個交叉軸。
.outter .inner{
background: gray;
width: 100px;
/* height: 100px; */
border: 1px solid #ccc;
box-sizing: border-box;
}
效果圖如下:
元素(子容器)的相關屬性
flex-basis:
定義了在分配多餘空間之前,項目佔據的主軸空間,瀏覽器根據這個屬性,計算主軸是否有多餘空間。
.item {
flex-basis: <length> | auto;
}
默認值:auto,即項目本來的大小, 這時候 item 的寬高取決於 width 或 height 的值。
當主軸爲水平方向的時候,當設置了 flex-basis,項目的寬度設置值會失效,flex-basis 需要跟 flex-grow 和 flex-shrink 配合使用才能發揮效果。
當 flex-basis 值爲 0 時,是把該項目視爲零尺寸的,故即使聲明該尺寸爲 140px,也並沒有什麼用。
當 flex-basis 值爲 auto 時,則跟根據尺寸的設定值(假如爲 100px),則這 100px 不會納入剩餘空間。
flex-grow:
設置元素是否需要擴大的比例。默認值爲0,即如果存在剩餘空間,也不放大。比如有以下代碼:
<view class='outter'>
<view class='inner inner1'>1</view>
<view class='inner inner2'>2</view>
</view>
wxss代碼爲:
.outter{
display: flex;
width: 300px;
height: 300px;
flex-wrap: wrap;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
border: 1px solid #ccc;
box-sizing: border-box;
}
.outter .inner1{
flex-grow: 2;
}
.outter .inner2{
flex-grow: 1;
}
效果圖爲:
因爲兩個元素分別佔了2份,1份,所以第一個元素是佔據了整個容器寬度的2/3,第二個元素佔據了整個容器寬度的1/3。另外,如果設置 flex-grow爲0,那麼他的寬度將會保持爲設置的寬度,如果寬度沒有設置,那麼將根據他的子元素
來保留寬度。假如代碼爲:
<view class='outter'>
<view class='inner inner1'>1</view>
<view class='inner inner2'>2</view>
</view>
wxss代碼爲:
.outter .inner1{
flex-grow: 0;
}
.outter .inner2{
flex-grow: 1;
}
效果圖爲:
如果把 inner1的 width刪掉,那麼效果圖爲:
flex-shrink屬性:
定義了項目的縮小比例,默認爲1,即如果空間不足,該項目將縮小。比如有以下代碼:
<view class='outter'>
<view class='inner inner1'>1</view>
<view class='inner inner2'>2</view>
<view class='inner'>3</view>
<view class='inner'>4</view>
</view>
wxss的代碼如下:
.outter{
display: flex;
width: 300px;
height: 300px;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
border: 1px solid #ccc;
box-sizing: border-box;
}
.outter .inner2{
flex-shrink: 0;
}
效果圖爲:
因爲給 inner2設置了 flex-shrink爲0,所以即使在空間不夠的情況下,他也不會被壓縮。
flex屬性:
flex屬性是 flex-grow flex-shrink flex-basis三個屬性的簡寫。假設以上三個屬性同樣取默認值,則 flex的默認值是 0 1 auto。
關於 flex的取值,有以下幾種方式:
1. auto:等價於 1 1 auto。也就是允許增長,允許縮小,寬度爲自動。
2. none:等價於 0 0 auto。也就是不允許增長,不允許縮小,寬度爲自動。
3. 非負數字:這個數字表示的是 flex-grow的值, flex-shrink爲1,表示允許縮小, flex-basis爲0%。可以認爲他就是把剩餘的空間進行填充。比如以下代碼是等價的:
.item {flex: 1;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
4. 0:對應的三個值分別爲 0 1 0%。比如以下代碼是等價的:
.item {flex: 0;}
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 0%;
}
5. 長度或者百分比:則這個值視爲 flex-basis的值,而 flex-grow爲1, flex-shrink爲1。比如以下代碼是等價
的:
.item-1 {flex: 0%;}
.item-1 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
.item-2 {flex: 24px;}
.item-2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 24px;
}
6. 兩個非負數字:分別視爲 flex-grow和 flex-shrink的值, flex-basis取 0%,如下是等同的:
.item {flex: 2 3;}
.item {
flex-grow: 2;
flex-shrink: 3;
flex-basis: 0%;
}
7. 一個非負數字和一個長度或百分比:則分別視爲 flex-grow 和 flex-basis 的值,flex-shrink 取 1,如下是等同
的:
.item {flex: 11 32px;}
.item {
flex-grow: 11;
flex-shrink: 1;
flex-basis: 32px;
}