CSS Podcast - 010:Flexbox
使用回應式設計時,有些設計模式可能會比較難以使用 內容。在可視區域有空間的情況下,這個模式非常實用,但在空間受限的情況下,這種固定版面配置可能會造成問題。
彈性方塊版面配置模型 (flexbox) 是一種為單維內容設計的版面配置模型。這特別適合處理尺寸不一的商品 並傳回這些項目的最佳版面配置
這是這個側欄模式的理想版面配置模型。 Flexbox 不只能協助內嵌側欄和內容 但空間不足時,側欄會換行顯示。 請不要設定瀏覽器只能遵循的固定維度 使用 Flexbox 改為提供彈性的邊界,以提示內容的顯示方式。
您可以使用 Flexbox 版面配置做哪些事?
Flex 版面配置具有下列功能: 您可在本指南中探索課程內容
- 可顯示為資料列或資料欄。
- 系統會遵循文件的書寫模式。
- 根據預設,這些字串為單行,但可以要求將其換行至多行。
- 版面配置中的項目可視覺重新排序,不受 DOM 中的順序影響。
- 空間可以分配到物品中 讓家長能夠根據家長的可用空間 調整大小
- 您可以使用「Box Alignment」屬性,在已折行的版面配置中,在項目和 Flex 行周圍分配空間。
- 各個項目本身可以對齊交叉軸。
主軸和交錯軸
要瞭解 Flexbox,關鍵在於瞭解主軸和交叉軸的概念。主要軸是 flex-direction
屬性所設定的軸。如果這是 row
,則你的主軸沿著列線。
如果為 column
,則主軸沿著欄長。
Flex 項目會以群組形式沿著主軸移動。提醒你,我們有許多內容,而我們正設法以群組形式呈現最適合的版面配置。
交錯軸會沿著主軸的另一個方向運作,因此如果 flex-direction
是 row
,交錯軸會沿著欄運作。
您可以在交叉軸上執行兩項操作。您可以個別移動項目,也可以將項目做為一組移動,讓項目與 Flex 容器對齊。此外,如果您已包裝 Flex 線
即可將這行程式碼視為群組,來控管這些行如何分配空間。
本指南將逐一介紹運作方式
但請注意,主要軸跟在 flex-direction
後方。
建立彈性容器
說明 Flexbox 如何由一組不同大小的項目使用,以及使用 Flexbox 放置物件 然後去蕪存菁。
<div class="container" id="container">
<div>One</div>
<div>Item two</div>
<div>The item we will refer to as three</div>
</div>
如要使用 Flexbox,您必須宣告要使用 Flex 格式設定情境,而非一般區塊和內嵌式版面配置。方法是將 display
屬性的值變更為 flex
。
.container {
display: flex;
}
如您在版面配置指南中所學,這會為您提供區塊層級方塊,其中包含 Flex 項目子項。彈性容器項目會立即開始顯示部分彈性容器行為,並使用初始值。
初始值代表:
- 項目會排成一列。
- 不會產生包裝。
- 不會填滿容器。
- 它們會在容器的開頭對齊。
控制項目的方向
即使您尚未新增 flex-direction
屬性,項目仍會以一列顯示,因為 flex-direction
的初始值為 row
。如果您需要新增資料列,則不必新增屬性。
如要變更方向,請新增屬性和下列四個值之一:
row
:項目以列的形式排列。row-reverse:
項目會從 Flex 容器的結尾排列成一列。column
:項目以欄形式排列。column-reverse
:從 Flex 容器結尾以資料欄形式排列的項目。
您可以利用下方示範中的項目群組測試所有價值。
反轉項目流程和無障礙功能
請謹慎使用任何會重新排序視覺顯示內容的屬性,以免影響無障礙功能。row-reverse
和 column-reverse
值就是很好的範例。
重新排序只會影響視覺順序,不會影響邏輯順序。請務必瞭解,因為邏輯順序是螢幕閱讀器朗讀的順序
內容
這樣所有透過鍵盤瀏覽的使用者都會跟著看見
在下列影片中,您可以看到如何反轉列的版面配置。 連結之間的 Tab 鍵會中斷連線,因為鍵盤導覽追蹤 DOM 而非視覺元素 螢幕。
任何可能會在 Flexbox 或格線中改變項目順序的行為,都可能會造成問題。 因此,任何重新排序作業都應進行徹底測試,確保不會讓部分使用者難以使用您的網站。
如需詳細資訊,請參閱:
書寫模式與方向
根據預設,Flex 項目是一列。 列會沿著句子在書寫模式和劇本方向流動。也就是說,如果你採用阿拉伯文 指令碼方向為由右至左 (rtl) 的指令碼方向時,委刊項會在右側對齊。 此外,分頁順序也會從右側開始,因為這是阿拉伯文朗讀句子的方式。
如果您使用的是垂直書寫模式 (例如某些日文字型),則一列會從上到下垂直顯示。請嘗試變更這個示範中使用垂直書寫模式的 flex-direction
。
因此,彈性項目的預設行為會連結至文件的編寫模式。 大多數教學課程都是以英文或其他橫向語言撰寫 由左至右書寫模式 這樣即可輕鬆假設彈性委刊項在「左側」放送,並水平放送。
考量主軸、交叉軸和書寫模式,我們在彈性容器中談論「開始」和「結束」,而非頂端、底部、左側和右側,可能會比較容易理解。每個軸都有開頭和結尾。 主軸的起點稱為 main-start。所以,Flex 系列的初始順序來自於主要開始 該軸的結尾是 main-end。交叉軸的起點為「跨軸」和「結束」。
包裝 Flex 項目
flex-wrap
屬性的初始值為 nowrap
。也就是說,如果容器的空間不足,項目就會溢出。
使用初始值顯示的項目會盡可能縮小,直到發生溢位為止,直到達到 min-content
大小為止。
為造成項目包裝,將 flex-wrap: wrap
新增至 Flex 容器。
.container {
display: flex;
flex-wrap: wrap;
}
當 Flex 容器換行時,會建立多個 Flex 行。在太空分佈方面 就像一個新的 Flex 容器 因此,如果您要將資料列換行,就無法讓第 2 列的內容與第 1 列上方的內容對齊。Flexbox 代表的是單一維度。 您可以控制單一軸、列或欄的對齊方式 因為在網格中,我們不能同時使用
Flex-flow (簡寫)
您可以使用簡寫 flex-flow
設定 flex-direction
和 flex-wrap
屬性。舉例來說,如要將 flex-direction
設為 column
並允許項目換行:
.container {
display: flex;
flex-flow: column wrap;
}
控制 Flex 項目內的空白
假設容器的空間比顯示項目所需的空間還多,項目會在開頭排列,且不會擴大填滿空間。並在內容大小達到上限時停止成長。這是因為 flex-
屬性的初始值為:
flex-grow: 0
:項目未成長。flex-shrink: 1
:項目可縮小至小於其flex-basis
。flex-basis: auto
:項目的基本大小為auto
。
這可以由關鍵字值 flex: initial
表示。flex
簡寫屬性、
flex-grow
、flex-shrink
和 flex-basis
的長音會套用至
彈性容器
如要讓項目變大,並讓大型項目比小型項目有更多空間,請使用 flex:auto
。你可以使用上方的示範內容來嘗試看看。
這會將屬性設為:
flex-grow: 1
:項目可以大於其flex-basis
。flex-shrink: 1
:項目可以縮小至小於其flex-basis
的項目。flex-basis: auto
:項目的基本大小為auto
。
使用 flex: auto
時,項目最終會顯示不同大小
因為每個項目之間會共用的空間,所以項目之間會由多個項目共用
最大內容大小
因此大型項目會增加更多空間。
強制所有項目採用一致的大小,並忽略內容大小從 flex:auto
變更為 flex: 1
的情況。
這會解壓縮為:
flex-grow: 1
:項目可以比flex-basis
更大。flex-shrink: 1
:項目可縮小至小於flex-basis
。flex-basis: 0
:項目的基本大小為0
。
使用 flex: 1
表示所有項目都沒有大小。
因此彈性容器中的所有空間都可供發布
由於所有項目的 flex-grow
因子皆為 1
,而這些項目會均等增長,而空間的共用方式也相同。
允許項目以不同速度成長
您不必為所有項目提供 flex-grow
因子 1
。您可以為 Flex 項目提供不同的 flex-grow
因子。在下方的示範中,第一個項目有 flex: 1
、第二個 flex: 2
和第三個 flex: 3
。
這些項目從 0
變大,因此彈性容器中的可用空間會共用為六個。
第一個項目會獲派一個部分
介於兩個部分
第三部分
您也可以透過 auto
的 flex-basis
執行相同的操作,但需要指定三個值。第一個值為 flex-grow
,第二個為 flex-shrink
,第三個為 flex-basis
。
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
由於這是使用 auto
的 flex-basis
的原因,因此較不常見。
可讓瀏覽器辨識空間分佈情形
不過,如果您想讓商品的成長幅度略高於演算法判斷的值,這項功能就很實用。
重新排序 Flex 項目
您可以使用 order
屬性重新排序 Flex 容器中的項目。這個屬性可讓一般群組中的項目排序。
項目會按照 flex-direction
決定的方向配置,
最低值
如有多個項目使用相同的值,系統會與其他含有該值的項目一併顯示。
以下舉例說明這個順序。
隨堂測驗
測驗您對 Flexbox 的瞭解
預設的 flex-direction
為
column
row
根據預設,Flex 容器會納入子項。
Flex 子項項目似乎被擠壓,哪個 Flex 屬性有助於緩解這個問題?
flex-shrink
flex-grow
flex-basis
Flexbox 對齊總覽
Flexbox 帶來一組屬性,可用於對齊項目和分配項目間的空間。這些屬性非常實用,自加入自己的規格後 以格狀版面配置顯示 以下說明 Flexbox 的運作方式。
這組屬性可分成兩個群組, 空間分佈的屬性和對齊屬性。 分配空間的屬性如下:
justify-content
:主軸上的空間分配。align-content
:跨軸的空間分佈情形。place-content
:設定上述兩個屬性的簡寫字。
Flexbox 中用於對齊的屬性:
align-self
:對齊交叉軸上的單一項目。align-items
:對齊交叉軸上的所有項目。
如果使用的是主軸,屬性的開頭會是 justify-
。
在交叉軸上,開頭為 align-
。
在主軸上分配空間
使用先前所示 HTML 時,Flex 項目會以一列方式排版,主軸上會保留空間。項目不夠大,無法完全填滿 Flex 容器。
由於 justify-content
的初始值為 flex-start
,因此項目會排列在 Flex 容器的開頭。項目會在開頭排列,任何額外的空格則會放在結尾。
將 justify-content
屬性新增至 Flex 容器。
設為 flex-end
而在容器末端則是對齊項目,備用空間則會放置在開始位置。
.container {
display: flex;
justify-content: flex-end;
}
您也可以使用 justify-content: space-between
在項目之間分配間距。
請試試示範中的部分值,並參閱 MDN 瞭解完整的可能值集。
前往 flex-direction: column
如果您已將 flex-direction
變更為 column
,justify-content
就會在該欄上運作。如要讓容器在做為欄使用時保留空白空間,您必須為容器提供 height
或 block-size
。否則就沒有多餘的空間可供分配。
請嘗試使用不同的值,這次使用彈性容器的欄版面配置。
在彈性線之間分配空間
使用包裝的 Flex 容器時,您可能會在交錯軸上有可用的空間。在這種情況下,您可以使用 align-content
屬性,並設定與 justify-content
相同的值。justify-content
會根據預設將項目對齊至 flex-start
,但 align-content
的初始值為 stretch
。將屬性 align-content
新增至 Flex 容器,即可變更該預設行為。
.container {
align-content: center;
}
請在示範中試試這個功能。這個範例包含折行的 Flex 項目,容器則包含 block-size
,以便我們保留一些空白空間。
place-content
簡寫
如要同時設定 justify-content
和 align-content
,您可以搭配使用 place-content
與一種方法
或兩個值
如果您同時指定第一個值用於 align-content
,第二個值用於 justify-content
,系統就會為兩個軸使用單一值。
.container {
place-content: space-between;
/* sets both to space-between */
}
.container {
place-content: center flex-end;
/* wrapped lines on the cross axis are centered,
on the main axis items are aligned to the end of the flex container */
}
對齊交叉軸上的項目
你也可以在交叉軸上,使用 align-items
對齊彈性線內的項目
和 align-self
。
這項對齊功能可用的空間取決於 Flex 容器的高度,或是在項目套用包裝時的 Flex 行。
align-self
的初始值為 stretch
。
因此根據預設,列中的彈性項目會延伸至最高項目的高度。
如要變更這個設定,請將 align-self
屬性新增至任何 Flex 項目。
.container {
display: flex;
}
.item1 {
align-self: flex-start;
}
請使用下列任一值讓項目對齊:
flex-start
flex-end
center
stretch
baseline
請參閱 MDN 的完整值清單。
接下來的示範包含單行含有 flex-direction: row
的 Flex 項目。最後一個項目會定義 Flex 容器的高度。第一個項目的 align-self
屬性的值為 flex-start
。
請嘗試變更該屬性的值,看看該屬性如何在交叉軸的空間中移動。
align-self
屬性會套用至個別項目。
align-items
屬性可套用至 Flex 容器,將所有個別 align-self
屬性設為群組。
.container {
display: flex;
align-items: flex-start;
}
在下一項示範中,請嘗試變更 align-items
的值,讓交叉線之間的所有項目保持一致
整理成一個軸
為什麼彈性容器中沒有 justify-self?
Flex 項目會在主軸上作為一組群組。 因此,沒有從該群組中分割個別項目的概念。
在格狀版面配置中,justify-self
和 justify-items
屬性可在內嵌軸上運作
讓項目在網格區域內對齊
由於彈性版面配置會將項目視為群組
這些屬性不會在彈性環境中實作。
值得一提的是,彈性容器確實能與自動邊距搭配使用。如果您需要將某個項目從群組中分割,或是將群組分割成兩個群組,可以套用邊界來執行這項操作。在下方範例中,最後一個項目的左邊空白為 auto
。自動邊界會依照套用的方向吸收所有空間。
也就是說,系統會將項目向右推,進而分割群組。
如何將項目置中對齊
對齊屬性可用於將項目置中,放置在另一個方塊中。justify-content
屬性會將項目對齊主軸 (即列)。跨軸的 align-items
屬性。
.container {
width: 400px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
進行隨堂測驗
測試您的 Flexbox 知識
.container {
display: flex;
direction: ltr;
}
如要與 Flexbox 垂直對齊,請使用
.container {
display: flex;
direction: ltr;
}
如要與 Flexbox 水平對齊,請使用
.container {
display: flex;
direction: ltr;
}
根據預設,Flex 項目會與 stretch
對齊。如果您想為子項使用內容大小,會使用下列哪種樣式?
align-content: start
align-items: flex-start
justify-content: flex-start
height: auto