前言:之前我寫過的一篇博客介紹CSS常用的幾種布局方式,PC端最常見的就是浮動布局和flex布局,而在移動端,由于不用顧忌IE這個業界大坑,flex布局應用的就更廣泛了,多以本文就來詳細的介紹一些flex布局。
1、先不說flex布局
首先我們回顧一下除了flex布局之外的常用布局方案:
首先是最基礎的normal flow(文檔流),子元素float+父元素添加clearfix類清除浮動,相對定位結合絕對定位,有時候還可以用負的margin來布局元素等等。而這些布局設定起來都相對比較復雜,要么得計算確切的位置,要么得防止浮動帶來的bug。直到flex布局的出現,人們有了更好的布局解決方案。
2、flex布局的特點
- 塊級布局側重垂直方向,行內布局側重水平方向,而flex布局就厲害了,他的布局與方向無關(或者說方向是可以改變的)
- flex布局可以實現空間的自動分配,自動對齊(恰好印證了flexible這個詞,彈性,靈活)
- flex布局適用于簡單的線性布局,更復雜的、多維度的布局要交給grid布局
3、flex中的基本概念
采用 Flex 布局的元素,稱為 Flex 容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為 Flex 項目(flex item),簡稱"項目"。
容器默認存在兩根軸:水平的主軸(main axis)和垂直的橫軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;橫軸的開始位置叫做cross start,結束位置叫做cross end。
項目默認沿主軸排列。單個項目占據的主軸空間叫做main size,占據的橫軸空間叫做cross size。
4、flex container 的屬性
-
flex-direction
:設置主軸的方向,屬性有:row (水平,默認值)/ row-reverse(水平反向) / column(豎直) / column-reverse(豎直反向) -
flex-wrap
:設置是否換行(默認為nowrap不換行),屬性有:nowrap / wrap / wrap-reverse(換行,且第一行在下面) -
flex-flow
:上面二者的簡寫,如:flex-flow: row wrap;
-
justify-content
:設置主軸的對齊方式,屬性有:flex-start(默認值) / flex-end / center / space-between (兩端對齊,項目之間的間隔都相等) / space-around (每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。) -
align-items
:設置橫軸的對齊方式,屬性有:flex-start / flex-end / center / baseline(按項目的第一行文字的基線對齊) / stretch(默認值,如果項目未設置高度或設為auto,將占滿整個容器的高度); -
align-content
:多行/列內容對齊方式(多行中間的間隔,單行則無效),屬性有:flex-start / flex-end / center / space-between / space-around / stretch
5、flex item 的屬性
-
flex-grow
:定義項目的放大比例,默認為0,即如果存在剩余空間,也不放大 -
flex-shrink
:定義了項目的縮小比例,默認為1,即如果空間不足,該項目將縮小。 -
flex-basis
:定義了在分配多余空間之前,項目占據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多余空間。它的默認值為auto,即項目的本來大小。 -
flex
:上面三個的縮寫,默認值為0 1 auto -
order
:順序(定義項目的排列順序。數值越小,排列越靠前,默認為0,可以為負數) -
align-self
:允許單個項目有與其他項目不一樣的對齊方式,可覆蓋align-items屬性。默認值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同于stretch,屬性有:auto | flex-start | flex-end | center | baseline | stretch
6、幾個簡單的例子
-
常見的手機頁面布局(topbar + main + tabs)
即全程不需要定位,浮動,僅用flex布局即可完成下圖的布局結構,中間的部分超出有滾動條,header和footer位置固定。
基本效果圖
html結構
<div class="container">
<header>header</header>
<main>
<ul>……</ul>
</main>
<footer>
<ul>……</ul>
</footer>
</div>
css關鍵代碼(部分省略)
.container{
display: flex;
flex-direction: column;
height: 100vh;
text-align: center;
}
.container > footer > ul{
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 80px;
}
.container > footer > ul > li{
background: #666;
width: 20%;
}
-
產品列表(
ul>li*9
)
即完成父元素定寬高,內容列表依次排版的效果,不需要float,不需要特別的計算margin,僅僅依靠flex布局即可完成下圖的基本布局:
效果圖
html基本結構
<ul class="container">
li{list$}*9
</ul>
css關鍵代碼
ul.container{
height: 400px;
width: 400px;
border: 1px solid red;
display: flex;
flex-flow: wrap row;
justify-content: space-between;
align-items: center;
}
ul.container > li{
width: 100px;
height: 100px;
border: 1px solid blue;
}
-
PC 頁面布局(用flex寫雙飛翼)
即header和footer定高,中間內容部分占滿空間;內容部分,需要content先加載(即先寫content代碼,使用order控制其顯示順序),conten寬度自適應,left和right定寬,在使用flex布局的情況下,代碼量遠小于使用浮動。效果圖如下:
效果圖
html結構
<div class="container">
<header>Header</header>
<main>
<div class="content">content</div>
<aside class="asideLeft">Left</aside>
<aside class="asideRight">Right</aside>
</main>
<footer>Footer</footer>
</div>
css關鍵代碼
.container{
display: flex;
flex-direction: column;
height: 100vh;
}
.container > header,footer{
min-height: 80px;
background: #aaa;
}
.container > main{
display: flex;
flex: 1;
}
.container > main > aside.asideLeft{
width: 100px;
background: #666;
order: 1;
}
.container > main > .content{
background: rgba(255,0,0,0.2);
flex:1;
order: 2;
}
.container > main > aside.asideRight{
width: 100px;
background: #666;
order: 3;
}
-
使用flex做成完美居中效果
使用flex布局非常容易做到完美居中的效果,可以實現內部寬高自適應居中,父元素只需要三行代碼:
display:flex;
justify-content:center;
align-items:center;
7、其他
兩個關于學習flex基本屬性的小游戲:
兩位大佬關于flex更細致的介紹: