CSS中Flex佈局的學習筆記
前言
最近,在學習一些前端知識。在學習的過程中發現會經常使用到Flex佈局,對這個知識點不太熟悉。因此,專門寫一篇文章來記錄一下學習歷程和心得。
本文的內容參考了網上公開的資料,其中主要參考了這兩個網址:CSS Flexible Box Layout Module Level 1和A Complete Guide to Flexbox。
什麼是Flex佈局
Flex佈局的英文是Flexbox Layout
,也可以稱為Flexible Box
,翻譯成中文的意思就是彈性盒子
,因為聽上去總感覺怪怪的,所以一般我們都很少直接使用中文翻譯。
Flex佈局的目的是希望即使在容器內大小未知或者動態情況下,提供一種更有效的容器內佈局、對齊和空間分配方式。換句話說,也就是Flex佈局賦予了容器具有能夠改變其內部的寬度、高度,甚至是順序等屬性,可以通過使用伸
縮
防止其溢位。
傳統的佈局通常使用block
和inline
來表示縱向佈局和水平佈局。與傳統的佈局相比,Flex佈局是一種與方向無關的佈局,其優點是能夠提供更好的靈活性,同時也能夠支援一些大型的複雜佈局,尤其是在其內部方向改變、大小重置、伸縮等情況。
基礎知識
Flex佈局是一個知識體系,它包括一系列的屬性值。其中這些屬性值中有些需要被宣告在父容器上,有些需要被宣告在子條目上。一個常規的Flex佈局應該宣告是flex
和它的direction
。網站[1]給出了這樣一張圖來描述它們之間的關係:
容器中的所有子檢視只可能沿著main axis
的main start
到main end
cross axis
的cross start
到cross end
排列,沒有其他情況。結合上圖,解釋一下它們的含義:
-
main axis
主軸是flex佈局中預設的排列方式。但是,可以通過設定flex-direction
來改變其排列方式。 -
main-start | main-end
預設的主軸排列方式是容器中的子檢視將自main-start
到main-end
排列。 -
main size
所有子檢視中的寬度的總和(包括內外佈局等)就是容器的寬度。所有子檢視中的高度的總和(包括內外佈局等)就是容器的高度。 -
cross axis
垂直於主軸的就是橫軸。橫軸始終與主軸保持垂直,其方向決定於主軸的方向。其實我們可以把上圖看成一個羅盤,在預設情況下主軸是自西向東,那麼此時的橫軸就是自北向南。若主軸通過flex-direction
-
cross-start | cross-end
預設的橫軸排列方式是容器中的子檢視將自cross-start
到cross-end
排列。 -
cross size
子檢視的高度或者寬度就是橫軸的大小。
Flex佈局的屬性
Flex佈局的屬性值有的只能在宣告在容器上,有的只能宣告在容器內的子條目上。如下圖,最外面的矩形方框是容器,容器內部的藍色背景色的方塊是子條目。
宣告在容器上的屬性
-
display
定義一個Flex的容器,容器的條目是inline
還是block
取決於宣告的值。.container { display: flex; /* or inline-flex */ }
-
flex-direction
設定主軸main-axis
的方向,目的是設定容器內子條目的排列方向。取值有四種情況,分別是row
、row-reverse
、column
和column-reverse
,與圖對應的關係就是:.container{ flex-direction: row | row-reverse | column | column-reverse; }
row
(預設): 從左到右row-reverse
: 從右到左column
: 從上到下column-reverse
: 從下到上
-
flex-wrap
預設情況下,子條目會在一排顯示。如果需要讓其換行,可以通過這個屬性來進行控制。
.container{ flex-wrap: nowrap | wrap | wrap-reverse; }
nowrap
(預設): 不換行wrap
: 換行wrap-reverse
: 翻轉換行
-
flex-flow
這個屬性是flex-direction
和flex-wrap
的組合,比如我們宣告樣式時,會這樣寫:.container{ flex-direction: row; flex-wrap: wrap; }
而現在,有了
flex-flow
這個屬性,我們就可以把上面兩行換成一行:.container{ flex-flow: row | wrap; }
-
justify-content
定義在主軸上的每排子條目的排列方式。取值有如下幾種情況:.container{ justify-content: flex-start | flex-end | start | end | left | right | center | space-between | space-around | space-evenly; }
flex-start
(預設): 沿著flex-direction
的方向靠近start
對齊。flex-end
: 沿著flex-direction
的方向靠近end
對齊。start
: 同flex-start
。end
: 同flex-end
。left
: 左對齊。right
: 右對齊。center
: 居中對齊。space-between
: 第一個子條目左對齊,最後一個右對齊,其餘均分。space-evenly
: 除了子條目佔據的空間外,其餘所有空間進行均分。space-around
: 在一行中對子條目進行均分,每一個子條目的左右兩邊的邊距相等。看上去好像感覺沒有均分,這是因為第一個和最後一個的邊只佔了一份,而中間的有兩份。就是這樣:
-
align-items
定義了子條目沿著橫軸across-axis
的排列方式。若想直觀看到效果,可以點選這裡。.container{ align-items: stretch | flex-start | flex-end | center | baseline; }
stretch
(預設):元素被拉伸以適應容器。如果指定側軸大小的屬性值為'auto',則其值會使專案的邊距盒的尺寸儘可能接近所在行的尺寸,但同時會遵照'min/max-width/height'屬性的限制。flex-start
:元素位於容器的開頭。flex-end
:元素位於容器的結尾。center
:元素位於容器的中心。baseline
:元素位於容器的基線上。如彈性盒子元素的行內軸與側軸為同一條,則該值與'flex-start'等效。其它情況下,該值將參與基線對齊。
-
align-content
在彈性容器內的各項沒有佔用交叉軸上所有可用的空間時對齊容器內的各項(垂直)。容器內必須有多行的專案,該屬性才能渲染出效果。.container { align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end; }
normal
(預設值)沒有設定任何值,就按照原始的方式進行排列。flex-start
元素位於容器的開頭。flex-end
元素位於容器的結尾。center
:元素位於容器的中心。space-between
元素位於各行之間留有空白的容器內。space-around
元素位於各行之前、之間、之後都留有空白的容器內。space-evenly
:元素之間的空間左右均分。stretch
:元素被拉伸以適應容器。start
:同flex-start
end
:同flex-end
宣告在容器內子條目的屬性
能夠宣告在子條目上的屬性有:order
、flex-grow
、flex-shrink
、flex-basis
、flex
、align-self
這幾個常用的屬性。
-
order
通常,子條目的順序按照程式碼中的前後順序進行渲染,但是在Flex佈局中可以通過使用order
關鍵字來進行子條目的重排。預設值為0,值越小,排序越靠前。值相同,則按照程式碼的先後順序進行排列。.item { order: 5; }
-
flex-grow[2]
grow
表示“擴大,增加”的意思,也就是說當父容器的寬度大於子條目的總和時,此時說明父容器不僅能容納所有的子條目,還有空餘的空間。此時,設定了該屬性值的條目就會根據設定的值進行擴充套件。若所有的子條目都設定成了1,那麼表示所有的條目將均分擴充套件容器。該屬性對負值無效。.item { flex-grow: 1; }
-
flex-shrink[2]
shrink
表示“收縮”的意思,也就是說當父容器的寬度小於子條目的總和時,此時說父容器無法容納所有的子條目,子條目溢位了父容器。此時,設定該屬性值就會根據設定的值進行收縮。.item { flex-shrink: 1; }
-
flex-basic
設定元素的寬度。若flex-basic
和width
一同設定,前者會覆蓋後者。 -
flex
為了簡化程式碼,使用flex
這個屬性來表示flex-grow
、flex-shrink
、flex-basis
這個三個屬性值,其中flex-shrink
和flex-basis
是可選的。flex
的預設值為none
,此時表示flex-grow:0
,flex-shrink:1
和flex-basis:auto
。.item { flex: none; }
等同於:
.item { flex-grow: 0; flex-shrink: 1; flex-basis: auto; }
-
align-self
父容器通過align-items
來控制子條目的位置,若需要子條目自己控制位置,而不受限於align-items
,可以通過使用align-self
來設定。.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
其值的含義與align-self
類似。
參考資料
[1]:A Complete Guide to Flexbox
[2]:桃園三兄弟之:flex-grow、flex-shrink、flex-basis詳解