一、背景
Flextbox Layout
(彈性盒佈局或伸縮盒佈局),提供了一種更加有效的方式去佈局、對齊和給容器中的子元素分配空間,即使他們的尺寸未知或者是動態改變的。 看看裏面有個flex
就能想象出來。
Flexbox layout
背後的設計理念:賦予容器去改變他的子元素的寬、高、排列順序的能力,從而可以更好的填充可用空間,尤其對各種各樣的設備和屏幕尺寸提供了便利的方式去佈局。一個具有flex特性的容器可以去拉伸他的子元素去填充可用的自由空間,也可以收縮他的子元素防止溢出。
更重要的一點,flextbox layout
的佈局方向也是不固定的。這點與我們以前的佈局是不同的。比如:block
是垂直佈局的,而inline
是水平佈局的。 對那些可以工作良好的頁面來說,他們在支持龐大或者複雜的應用方面缺乏靈活性。尤其當面對設備的方向、尺寸、縮放等等方面發生改變的時候,這種缺點更加明顯。
二、基本知識
flexbox
是一個完整的模塊,而不是一個單一的屬性。
flexbox
加入了大量的屬性。這些屬性一部分用在容器上(父元素,一般稱之爲 flex container
),而另外的一些是用在子元素上(一般稱之爲 flex items
. 彈性項目)。
下面介紹一些基本概念:
這張圖來自w3c規範。
一般情況下,flex itmes
要麼沿着 main axis
佈局(從主軸起點到主軸重點),要麼沿着 cross axis
佈局(從側軸起點到側軸重點)。
- 主軸(main axis) : 彈性容器的主軸是最主要的軸,flex items會沿着這條軸被佈局。有一點需要注意:主軸不一定總是水平的,他的方向由
flex-direction
屬性的值來決定。(後面後細講) - 主軸起點(main start)和主軸終點(main end):彈性容器中的 flex items 會從 主軸起點 開始 到主軸重點結束 佈局。
- 主軸長度(main size):flex item的寬或高就是主軸長度。到底是寬還是高,由誰沿着主軸的方向來決定。
- 側軸(cross axis):垂直於主軸的軸就是側軸。側軸的方向由主軸來決定。
- 側軸起點(cross start )和側軸終點(cross end):彈性行(flex lines)從側軸起點開始到側軸重點結束。
- 側軸長度(cross size):伸縮項目的在側軸方向的寬度或高度就是項目的側軸長度,伸縮項目的側軸長度屬性是「
width
」或「height
」屬性,由哪一個沿着着側軸方向決定。
三、flex container的屬性
3.1 display
這個屬性把一個元素定義成爲 flex container。可以設置爲 flex
或 inline-flex
。設置爲flex
容器就是塊級容器,設置爲 inline-flex
就是行內元素。 這個容器就會成爲他們的直接子元素的 flex context
.container {
display: flex; /* or inline-flex */
}
3.2 flex-direction
這個屬性創建主軸,定義了 flex items
在彈性容器中佈局的方向。主軸要麼水平方向,要麼垂直方向。
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row : 主軸水平,方向從左向右。(默認值)
- row-reverse:主軸水平,方向從右向左
- column : 主軸垂直,方向從上向下
- column-reverse:主軸垂直,方向從下向上
3.3 flex-wrap
默認情況下,所有的flex items
都會試圖在一行。通過修改這個屬性的值,可以讓 flex items
按照要求多行排列。其實這個屬性可以定義 flex items
在側軸方向的排序方式。
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap :所有的
flex items
在一行。(默認值) - wrap :允許
flex items
自動換行在多行,方向是從上向下。 - wrap-reverse : 允許
flex items
自動換行在多行,方向是從下向上。
html:
<div class='container'>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
css:
* {
margin: 0;
padding: 0;
}
.container {
display: flex;
width: 700px;
height: 500px;
background-color: gray;
flex-direction: row;
flex-wrap: nowrap;
}
p{
width : 200px;
height : 200px;
background-color : pink;
}
p:nth-child(2n){
background-color: cornflowerblue;
}
效果1:
效果2:
效果3:
效果4:
效果5:
效果6:
3.4 flex-flow
flex-flow
是flex-direction
和 flex-wrap
兩個屬性的合併簡寫方式。一次性的定義了主軸和側軸,他的默認值是:row nowrap
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
3.5 justify-content
該屬性定義了主軸方向flex items
的對齊方式。也能把多餘的自由空間,分配給flex-items
。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
- flex-start:
flex-items
從主軸起點開始排列。
- flex-end:
flex-items
從主軸終點開始排列。
- center:
flex-items
在主軸方向居中排列。
- space-between:把 free space 平局分佈在
flex-items
之間。第一個 item緊挨着主軸起點,最後一個item緊挨着主軸終點。
space-around:把
free space
平均分佈在每個item的周圍。所以中間空白會比邊上的空白大一倍。
3.6 align-items
該屬性定義了flex-items
在側軸上的對齊方式。可以看成是justify-content
在側軸上的版本。
如果是單行flex-items
的情況使用比較好
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
- flex-start:從側軸起點開始排列
- flex-end:從側軸的終點開始排列
- center:沿着側軸方向居中
- baseline:沿着內容的基線對齊
- stretch:在側軸方向拉伸
flex-items
。(默認值)。但是他的優先級比設定了具體的heigth
和max-height
低,但是比auto高。
3.7 align-content
該屬性定義了當有多行flex items
時,free-space
如何分佈,類似於主軸的justify-content
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
- flex-start:從側軸起點開始排列
- flex-end:從側軸的終點開始排列
- center:沿着側軸方向居中
- stretch:在側軸方向拉伸
flex-items
。(默認值)。但是他的優先級比設定了具體的heigth
和max-height
低,但是比auto高。 - space-between:把 free space 平局分佈在
flex-items
之間。第一個 item緊挨着側軸起點,最後一個item緊挨着側軸終點。 - space-around:把
free space
平均分佈在每個item的周圍。所以中間空白會比邊上的空白大一倍。
四、flex-items的屬性
4.1 order
默認情況下,flex-items
安裝源碼的屬性佈局。然後,通過 order
屬性可以改變他們在彈性容器中的出現的順序。
.item {
order: <integer>;
}
order
的默認默認值是 0 。值越大,佈局越靠後; 反之,越小,佈局越靠前。
.child:nth-child(2){
order: 2;
}
.child:nth-child(3){
order: 1;
}
4.2 flex-grow
該屬性設置 flex-item
在主軸方向,有空餘空間的時候可以佔據空餘空間。他的值是一個沒有單位的值,表示佔據空餘空間的比例。
默認值是 0。負值無效
.item {
flex-grow: <number>; /* default 0 */
}
比如:
如果有2個item都設置爲 1, 則他們會把剩餘的平分, 因爲分別是: 1 / (1 + 1) * 剩餘空間、1 / (1 + 1) * 剩餘空間
如果3個item 分別設置爲 2、1、3 。則他們分別分的剩餘空間的 2 / (2 + 1 + 3) * 剩餘空間、1 / (2 + 1 + 3)* 剩餘空間、3 / (2 + 1 + 3)* 剩餘空間
總結: flex-grow / 所有的flex-grow只和 * 剩餘空間
.item:nth-child(1){
flex-grow: 1;
}
.item:nth-child(2){
flex-grow: 1;
}
.item:nth-child(1){
flex-grow: 1;
}
.item:nth-child(3){
flex-grow: 2;
}
4.3 flex-shrink
該屬性讓 flex-item
具有收縮的功能。當一行放不下,並且不允許換行的時候,允許 flex-item收縮。
值是一個整數,來表示收縮比率。默認值是1。 如果是0表示不允許收縮。
一行放不下的時候,其實表示的是剩餘空間爲負,計算方法同 flex-grow
是一樣的,只是現在是減去響應的值而已(加負)
.container{
height : 200px;
width: 600px;
background-color : gray;
display: flex;
}
.item{
height:100px;
width: 300px;
background-color: pink;
margin: 50px 0 0 0px;
font-size: 60px;
text-align: center;
line-height: 100px;
}
.item:nth-child(2n){
background-color: cornflowerblue;
}
.item:nth-child(1){
flex-shrink: 2;
}
.item:nth-child(3){
flex-shrink: 3;
}
計算:
剩餘空間: 600 - 3 * 300 = -300
剩餘空間每份: -300 / (2 + 1 + 3) = -50
item1寬度: 300 - 50 * 2 = 200
item1寬度: 300 - 50 * 1 = 250
item1寬度: 300 - 50 * 3 = 150
4.4 flex-basis
這個屬性指定在剩餘空間分配之前,flex-item
的尺寸。
.item {
flex-basis: <length> | auto; /* default auto */
}
- 可以指定具體的長度
px、em、百分比
- auto:意思是參考這個item的寬或高。 默認值是auto
.container{
width: 900px;
display: flex;
}
.item{
width: 200px;
background-color: pink;
}
.item:nth-child(1){
flex-grow: 1;
flex-basis: auto; //
}
.item:nth-child(3){
flex-grow: 1;
flex-basis: 60px; //
}
剩餘空間: 900 - 200 - 200 - 60 = 440
item1 : 200 + 220 = 420
item2:200
item3:60 + 220 = 280
4.5 flex
是flex-grow、flex-shrink、flex-basis
的簡寫。 flex-shrink、flex-basis
這2個參數是可選的。 默認值是:0 1 auto
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
強烈建議使用這個簡寫的形式來代替3個獨立的屬性。 簡寫可以智能設置其他的值。
4.6 align-self
單獨的設置某個 item 的對齊方式,來覆蓋align-items或align-content。
.container {
height: 200px;
width: 900px;
background-color: gray;
display: flex;
align-items: flex-start;
}
.item:nth-child(3) {
flex-grow: 1;
flex-basis: 0px;
align-self: flex-end;
}
參考文章: