Flexbox

CSS Podcast - 010:Flexbox

使用回應式設計時,有些設計模式可能會比較難以使用 內容。在可視區域有空間的情況下,這個模式非常實用,但在空間受限的情況下,這種固定版面配置可能會造成問題。

彈性方塊版面配置模型 (flexbox) 是一種為單維內容設計的版面配置模型。這特別適合處理尺寸不一的商品 並傳回這些項目的最佳版面配置

這是這個側欄模式的理想版面配置模型。 Flexbox 不只能協助內嵌側欄和內容 但空間不足時,側欄會換行顯示。 請不要設定瀏覽器只能遵循的固定維度 使用 Flexbox 改為提供彈性的邊界,以提示內容的顯示方式。

您可以使用 Flexbox 版面配置做哪些事?

Flex 版面配置具有下列功能: 您可在本指南中探索課程內容

  • 可顯示為資料列或資料欄。
  • 系統會遵循文件的書寫模式。
  • 根據預設,這些字串為單行,但可以要求將其換行至多行。
  • 版面配置中的項目可視覺重新排序,不受 DOM 中的順序影響。
  • 空間可以分配到物品中 讓家長能夠根據家長的可用空間 調整大小
  • 您可以使用「Box Alignment」屬性,在已折行的版面配置中,在項目和 Flex 行周圍分配空間。
  • 各個項目本身可以對齊交叉軸。

主軸和交錯軸

要瞭解 Flexbox,關鍵在於瞭解主軸和交叉軸的概念。主要軸是 flex-direction 屬性所設定的軸。如果這是 row,則你的主軸沿著列線。 如果為 column,則主軸沿著欄長。

三個彼此相連的方塊,旁邊有一個箭頭,指向右方。箭頭已標示「主軸」標籤

Flex 項目會以群組形式沿著主軸移動。提醒你,我們有許多內容,而我們正設法以群組形式呈現最適合的版面配置。

交錯軸會沿著主軸的另一個方向運作,因此如果 flex-directionrow,交錯軸會沿著欄運作。

三個不同高度的方塊,彼此各有一支箭頭,指向左。箭頭標示為「主軸」。這裡有一個指向底部的箭頭。這是標有「跨軸」標籤的圖表

您可以在交叉軸上執行兩項操作。您可以個別移動項目,也可以將項目做為一組移動,讓項目與 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-reversecolumn-reverse 值就是很好的範例。 重新排序只會影響視覺順序,不會影響邏輯順序。請務必瞭解,因為邏輯順序是螢幕閱讀器朗讀的順序 內容 這樣所有透過鍵盤瀏覽的使用者都會跟著看見

在下列影片中,您可以看到如何反轉列的版面配置。 連結之間的 Tab 鍵會中斷連線,因為鍵盤導覽追蹤 DOM 而非視覺元素 螢幕。

任何可能會在 Flexbox 或格線中改變項目順序的行為,都可能會造成問題。 因此,任何重新排序作業都應進行徹底測試,確保不會讓部分使用者難以使用您的網站。

如需詳細資訊,請參閱:

書寫模式與方向

根據預設,Flex 項目是一列。 列會沿著句子在書寫模式和劇本方向流動。也就是說,如果你採用阿拉伯文 指令碼方向為由右至左 (rtl) 的指令碼方向時,委刊項會在右側對齊。 此外,分頁順序也會從右側開始,因為這是阿拉伯文朗讀句子的方式。

如果您使用的是垂直書寫模式 (例如某些日文字型),則一列會從上到下垂直顯示。請嘗試變更這個示範中使用垂直書寫模式的 flex-direction

因此,彈性項目的預設行為會連結至文件的編寫模式。 大多數教學課程都是以英文或其他橫向語言撰寫 由左至右書寫模式 這樣即可輕鬆假設彈性委刊項在「左側」放送,並水平放送。

考量主軸、交叉軸和書寫模式,我們在彈性容器中談論「開始」和「結束」,而非頂端、底部、左側和右側,可能會比較容易理解。每個軸都有開頭和結尾。 主軸的起點稱為 main-start。所以,Flex 系列的初始順序來自於主要開始 該軸的結尾是 main-end。交叉軸的起點為「跨軸」和「結束」

上述字詞的有標籤圖表

包裝 Flex 項目

flex-wrap 屬性的初始值為 nowrap。也就是說,如果容器的空間不足,項目就會溢出。

一個內含九個項目的 Flex 容器,項目已縮小,因此一行只顯示一個字詞,但沒有足夠的空間可並排顯示,因此 Flex 項目已延伸到容器的方塊外。
一旦達到最小內容大小,Flex 項目就會開始溢出容器

使用初始值顯示的項目會盡可能縮小,直到發生溢位為止,直到達到 min-content 大小為止。

為造成項目包裝,將 flex-wrap: wrap 新增至 Flex 容器。

.container {
  display: flex;
  flex-wrap: wrap;
}

當 Flex 容器換行時,會建立多個 Flex 行。在太空分佈方面 就像一個新的 Flex 容器 因此,如果您要將資料列換行,就無法讓第 2 列的內容與第 1 列上方的內容對齊。Flexbox 代表的是單一維度。 您可以控制單一軸、列或欄的對齊方式 因為在網格中,我們不能同時使用

Flex-flow (簡寫)

您可以使用簡寫 flex-flow 設定 flex-directionflex-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-growflex-shrinkflex-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 變大,因此彈性容器中的可用空間會共用為六個。 第一個項目會獲派一個部分 介於兩個部分 第三部分

您也可以透過 autoflex-basis 執行相同的操作,但需要指定三個值。第一個值為 flex-grow,第二個為 flex-shrink,第三個為 flex-basis

.item1 {
  flex: 1 1 auto;
}

.item2 {
  flex: 2 1 auto;
}

由於這是使用 autoflex-basis 的原因,因此較不常見。 可讓瀏覽器辨識空間分佈情形 不過,如果您想讓商品的成長幅度略高於演算法判斷的值,這項功能就很實用。

重新排序 Flex 項目

您可以使用 order 屬性重新排序 Flex 容器中的項目。這個屬性可讓一般群組中的項目排序。 項目會按照 flex-direction 決定的方向配置, 最低值 如有多個項目使用相同的值,系統會與其他含有該值的項目一併顯示。

以下舉例說明這個順序。

隨堂測驗

測驗您對 Flexbox 的瞭解

預設的 flex-direction

row
根據預設,彈性容器會將項目排入一列,並在開頭排列。開啟包裝功能後,系統會繼續建立資料列,讓子項繼續流動。
column
將 flex-direction 設為 column 是堆疊元素的絕佳方式,但並非預設值。

根據預設,Flex 容器會納入子項。

true
必須啟用包裝功能。
false
搭配使用 flex-wrap: wrapdisplay: flex 以納入子項

Flex 子項項目似乎被擠壓,哪個 Flex 屬性有助於緩解這個問題?

flex-grow
這項屬性說明元素是否可超出基礎大小,而非在基礎下應如何運作。
flex-shrink
是,此屬性說明在寬度低於基礎時如何處理大小調整。
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 變更為 columnjustify-content 就會在該欄上運作。如要讓容器在做為欄使用時保留空白空間,您必須為容器提供 heightblock-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-contentalign-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-selfjustify-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 對齊。如果您想為子項使用內容大小,會使用下列哪種樣式?

justify-content: flex-start
左右屬性為水平對齊,而非垂直對齊。
align-content: start
content 會對齊 Flex 線條,而非對齊子項項目。
height: auto
這不會有任何影響。
align-items: flex-start
是,我們想垂直對齊「頂部」或 start,即可移除預設延展值,改用內容高度。

資源