徹底理解 CSS Flexbox 佈局,看這一篇就夠了!
一、Flexbox 佈局的概念
Flexbox 佈局也叫 Flex 佈局,彈性盒子佈局。它的目標是提供一個更有效地佈局、對齊方式,並且能夠使父元素在子元素的大小未知或動態變化情況下仍然能夠分配好子元素之間的間隙。主要思想是使父元素能夠調整子元素的寬度、高度、排列方式,從而更好的適應可用的佈局空間。設定爲 flex 佈局的元素能夠放大子元素使之儘可能填充可用空間,也可以收縮子元素使之不溢出。
Flex 佈局更適合小規模的佈局,可以簡便、完整、響應式的實現各種頁面佈局。但是,設爲 Flex 佈局以後,其子元素的float
、clear
和vertical-align
屬性將失效。Flex 彈性盒模型的優勢在於只需聲明佈局應該具有的⾏爲,⽽不需要給出具體的實現⽅式,瀏覽器負責完成實際佈局,當佈局涉及到不定寬度,分佈對⻬的場景時,就要優先考慮彈性盒佈局。
Flex 佈局是一個完整的模塊,它包括了一套完整的屬性。其中採用 Flex 佈局的元素,稱爲 Flex 容器,簡稱 " 容器 "。它的所有子元素就是容器成員,稱爲 Flex 項目,簡稱" 項目 "。
容器默認存在兩個軸:水平軸(main axis)和垂直軸(cross axis),項目默認沿主軸排列(水平軸):
這裏面涉及到了幾個概念,下面來看一下:
- main axis: Flex 父元素的主軸是指子元素佈局的主要方向軸,它由屬性 flex-direction 來確定主軸是水平還是垂直的,默認爲水平軸。
- main-start & main-end: 分別表示主軸的開始和結束,子元素在父元素中會沿着主軸從 main-start 到 main-end 排布。
- main size: 單個項目佔據主軸的長度大小。
- cross axis: 交叉軸,與主軸垂直。
- cross-start & cross-end: 分別表示交叉軸的開始和結束。子元素在交叉軸的排布從 cross-start 開始到 cross-end。
- cross size: 子元素在交叉軸方向上的大小。
二、父元素屬性
想要使用 flex 佈局,首先需要給父元素指定爲 flex 佈局,這樣容器內的元素才能實現 flex 佈局:
<div></div>
.container {
display: flex | inline-flex;
}
複製代碼
這裏有兩種方式可以設置 flex 佈局,使用display: flex;
會生成一個塊狀的 flex 容器盒子,使用display: inline-flex;
會生成一個行內的 flex 容器盒子。如果我們使用塊狀元素,比如 div 標籤,就可以使用 flex,如果使用行內元素,就可以使用 inline-flex。多數情況下,我們會使用 display: flex;。
父元素(容器)可以設置以下六個屬性:
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
1. flex-direction
flex-direction:主軸方向,它決定了容器內元素排列方向,它有四個屬性值:
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
複製代碼
(1)flex-direction: row
:默認值,沿水平主軸從左到右排列,起點在左沿
(2)flex-direction: row-reverse
:沿水平主軸從右到左排列,起點在右沿
(3)flex-direction: column
:沿垂直主軸從上到下排列,起點在上沿
(4)flex-direction: column-reverse
:沿垂直主軸從下到上排列,起點在下沿
2. flex-wrap
flex-wrap:容器內元素是否可以換行,它有三個屬性值:
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
複製代碼
(1)flex-wrap: nowrap
:默認值,不換行。當主軸的長度是固定並且空間不足時,項目尺寸會隨之進行調整,而不會換行。
(2)flex-wrap: wrap
:換行,第一行在上面
(3)flex-wrap: wrap-reverse
:換行,第一行在下面
3. flex-flow
flex-flow
是 flex-direction
屬性和flex-wrap
屬性的簡寫,默認爲:flex-flow:row nowrap
,用處不大,最好還是分開來寫。該屬性的書寫格式如下:
.container {
flex-flow: <flex-direction> <flex-wrap>;
}
複製代碼
4. justify-content
justify-content:元素在主軸的對齊方式,它有五個屬性值:
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
複製代碼
這裏以水平方向爲主軸進行舉例,即 flex-direction: row。
(1)justify-content : flex-start
:默認值,元素在主軸上左對齊(上對齊)
(2)justify-content : flex-end
:元素在主軸上右對齊(下對齊)
(3)justify-content : center
:元素在主軸上居中對齊
(4)justify-content : space-between
:元素在主軸上兩端對齊,元素之間間隔相等
(5)justify-content : space-around
:每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。
5. align-items
align-item:元素在交叉軸上的對齊方式,它有五個屬性值:
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
複製代碼
這裏以水平方向爲主軸進行舉例,即 flex-direction: row。
(1)align-item:flex-start
:交叉軸的起點對齊(上面或左邊)。設置容器高度爲 100px,項目高度分別爲 20px、40px、60px、80px、100px,效果如圖所示:
(2)align-item:flex-end
:交叉軸的終點對齊(下面或右邊)。設置容器高度爲 100px,項目高度分別爲 20px、40px、60px、80px、100px,效果如圖所示:
(3)align-item:center
:交叉軸的中點對齊。設置容器高度爲 100px,項目高度分別爲 20px、40px、60px、80px、100px,效果如圖所示:
(4)align-item:stretch
:默認值、如果元素未設置高度或設爲 auto,將佔滿整個容器的高度。假設容器高度設置爲 100px,而項目沒有設置高度,則項目的高度也爲 100px:
(5)align-item:baseline
:以元素的第一行文字的基線對齊
6. align-content
align-content:多根軸線對齊方式。如果元素只有一根軸線,該屬性不起作用。它有六個屬性值:
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
複製代碼
那這個軸線數怎麼確定呢?實際上這主要是由 flex-wrap 屬性決定的,當 flex-wrap 設置爲 nowrap 時,容器僅存在一根軸線,因爲項目不會換行,就不會產生多條軸線。當 flex-wrap 設置爲 wrap 時,容器可能會出現多條軸線,這時就需要去設置多條軸線之間的對齊方式。
這裏以水平方向爲主軸時舉例,即:flex-direction: row; flex-wrap: wrap;
(1)align-content: stretch
:默認值,軸線佔滿整個交叉軸。這裏我們先設置每個項目都是固定寬度,效果如下:
下面就去掉每個項目的高度,它會佔滿整個交叉軸,效果如下:
(2)align-content: flex-start
:從交叉軸開始位置填充
(3)align-content: flex-end
:從交叉軸結尾位置填充
(4)align-content: center
:與交叉軸中點對齊
(5)align-content: space-between
:與交叉軸兩端對齊,軸線之前的間隔平均分佈
(6)align-content: space-around
:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍
三、子元素屬性
子元素有以下六個屬性:
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
1. order
order
屬性用來定義項目的排列順序。數值越小,排列越靠前,默認爲0
。使用形式如下:
.item {
order: <integer>;
}
複製代碼
2. flex-basis
flex-basis
屬性定義了在分配多餘空間之前,項目佔據的主軸空間,瀏覽器會根據這個屬性來計算主軸是否有多餘空間。它的默認值爲 auto,即項目的本來大小。使用形式如下:
.item {
flex-basis: <length> | auto;
}
複製代碼
當主軸設置爲水平時,當設置了 ** **flex-basis,設置的項目寬度值會失效,flex-basis
需要跟 flex-grow
和 flex-shrink
配合使用才能生效。有兩種特殊的值:
- 當
flex-basis
值爲 0 % 時,項目尺寸會被認爲是 0,因此無論項目尺寸設置多少都用; - 當
flex-basis
值爲 auto 時,則跟根據尺寸的設定值來設置大小。
3. flex-grow
flex-grow
屬性定義項目的放大比例,默認爲 0,即如果存在剩餘空間時也不放大。
當容器中所有的項目都設置了 flex-basis 屬性時,如果仍有是剩餘的空間,設置的 flex-grow
屬性才能生效。
- 如果所有項目的 flex-grow 屬性都設置爲 1,那麼它們會均分剩餘的空間,如下圖所示:
- 如果其中一個項目的 flex-grow 屬性設置爲 2,其他均爲 1,那麼它佔據的剩餘空間就是其他項目的兩倍,如下圖所示:
3. flex-shrink
flex-shrink
屬性定義了項目的縮小比例,默認爲 1,即如果空間不足,該項目將縮小。不能設置負值,使用形式如下:
.item {
flex-shrink: <number>;
}
複製代碼
- 如果所有項目的 flex-shrink 屬性都爲 1,當空間不足時,都將等比例縮小,如下圖所示:
- 如果一個項目的 flex-shrink 屬性爲 0,其他項目都爲 1,則空間不足時,前者不縮小,如下圖所示:
5. flex
flex
屬性是flex-grow
, flex-shrink
和 flex-basis
的簡寫,後兩個屬性可選。默認值爲:flex:0 1 auto。
使用形式如下:
.item{
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
複製代碼
對於 flex 的取值有幾種常用的特殊情況: (1)默認值:flex:0 1 auto,即在有剩餘空間時,只放大不縮小
.item {
flex:0 1 auto;
}
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
複製代碼
(2)flex: none,即有剩餘空間時,不放大也不縮小,最終尺寸通常表現爲最大內容寬度。
.item {
flex:0 0 auto;
}
.item {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
}
複製代碼
(3)flex: 0,即當有剩餘空間時,項目寬度爲其內容的寬度,最終尺寸表現爲最小內容寬度。
.item {
flex:0 1 0%;
}
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 0%;
}
複製代碼
(4)flex: auto,即元素尺寸可以彈性增大,也可以彈性變小,具有十足的彈性,但在尺寸不足時會優先最大化內容尺寸。
.item {
flex:1 1 auto;
}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
}
複製代碼
(5)flex: 1,即元素尺寸可以彈性增大,也可以彈性變小,具有十足的彈性,但是在尺寸不足時會優先最小化內容尺寸,
.item {
flex:1 1 0%;
}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
複製代碼
6. align-self
align-self
屬性允許單個項目有與其他項目不一樣的對齊方式,可覆蓋align-items
屬性。默認值爲auto
,表示繼承父元素的align-items
屬性,如果沒有父元素,則等同於stretch
。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
複製代碼
這個屬性和 align-items 屬性的效果是一樣的,只不過這個屬性只對單個項目生效,而 align-items 是對容器中所有的項目生效。
設置容器的 align-items 屬性爲 flex-start,容器中第三個項目的 align-self 屬性爲 flex-end,效果如下:
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://juejin.cn/post/7004622232378966046