Flexbox

CSS Podcast - 010:Flexbox

使用回應式設計時,有些設計模式可能會比較難以使用 內容。有可視區域空間時 這種模式的效果很好 但空間是壓縮式的 所以如果採用嚴謹的版面配置,也會造成問題

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

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

彈性版面配置有哪些用途?

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

  • 可顯示為列或欄。
  • 系統會遵循文件的書寫模式。
  • 系統預設會以單行顯示 但可以要求換行
  • 版面配置中的項目能以視覺化方式重新排序 與物件在 DOM 中的順序相差
  • 空間可以分配到物品中 讓家長能夠根據家長的可用空間 調整大小
  • 空間可以在換行的版面配置中分配至項目和彈性線條。 使用 Box 對齊屬性。
  • 各個項目本身可以對齊交叉軸。

主軸和交叉軸

瞭解彈性尺寸的關鍵是瞭解主軸和交叉軸的概念。 主軸是指 flex-direction 屬性所設定的軸。 如果這個值是 row,請將主軸沿著列線移動 如果為 column,則主軸沿著欄長。

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

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

交叉軸會朝向主軸的另一方向延伸, 因此,如果 flex-directionrow,交叉軸就會沿著資料欄執行。

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

您可以在交叉軸上進行兩項操作。 您可以個別或群組來移動項目,讓項目彼此對齊和彈性 都會在 Docker 容器中執行此外,如果您已包裝 Flex 線 即可將這行程式碼視為群組,來控管這些行如何分配空間。 本指南將逐一介紹運作方式 但請注意,主要軸跟在 flex-direction 後方。

建立 Flex 容器

說明 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 項目會使用其初始值,立即開始呈現一些 Flexbox 行為。

初始值代表:

  • 項目會排成一列。
  • 容器並不會自動換行。
  • 不會成長來填滿容器。
  • 它們會在容器的開頭對齊。

控制項目方向

即使您尚未新增 flex-direction 屬性 因為 flex-direction 的初始值為 row,所以項目顯示為一列。 如果您需要新增資料列,則不必新增屬性。 如要變更方向,請加入屬性和下列任一值之一:

  • row:項目以列的形式排列。
  • row-reverse: 項目會在彈性容器結尾以一列方式排列。
  • column:項目以資料欄的形式版面配置。
  • column-reverse:從 Flex 容器結尾以資料欄形式排列的項目。

您可以利用下方示範中的項目群組測試所有價值。

改變項目流程和無障礙功能

使用任何屬性重新排序視覺顯示時,請務必小心 順序在於避免在 HTML 文件中排列順序 因為這可能會導致無障礙體驗產生負面影響 row-reversecolumn-reverse 值就是很好的範例。 重新排序只會以視覺順序排列,不會發生邏輯順序。 請務必瞭解,因為邏輯順序是螢幕閱讀器朗讀的順序 內容 這樣所有透過鍵盤瀏覽的使用者都會跟著看見

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

任何可能會在 Flexbox 或格線中改變項目順序的行為,都可能會造成問題。 因此,任何重新排序都應執行全面測試,確認不會導致你的網站無法順利上架 讓某些人難以使用

如需詳細資訊,請參閱:

書寫模式與方向

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

如要使用垂直書寫模式 (例如某些日文字體) 之後,系統會從上到下垂直排列一列。 在這個採用垂直書寫模式的示範中,請嘗試變更 flex-direction

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

透過主軸和交叉軸再加上寫作模式後 我們介紹了 startend,而不是上、下、左、右 不妨考慮使用 Flexbox。 每個軸都有開頭和結尾。 主要軸的起點稱為「main-start」。 所以,Flex 系列的初始順序來自於主要開始 該軸的結尾為 main-end。 交叉軸的起點為「跨軸」和「結束」

上述字詞的有標籤圖表

包裝 Flex 項目

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

Flex 容器內共有九個項目,項目已縮減,因此一行佔一個字詞
但是空間不足以並排顯示,所以 Flex 項目擴展到
方塊內
達到最小內容大小彈性項目後,就會開始溢出容器

使用初始值顯示的項目會盡可能縮小 調整為 min-content 大小才會溢位

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

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

當彈性容器包裝時,會建立多個「彈性線」。 在太空分佈方面 就像一個新的 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:autoflex: 1

這個解壓縮套件適用於:

  • flex-grow: 1:項目可以大於其 flex-basis
  • flex-shrink: 1:項目可以縮小至小於其 flex-basis 的項目。
  • flex-basis: 0:項目的基本大小為 0

使用 flex: 1 表示所有項目都沒有大小。 因此彈性容器中的所有空間都可供發布 由於所有項目的 flex-grow 因子皆為 1,而這些項目會均等增長,而空間的共用方式也相同。

讓商品以不同費率成長

您不需要將所有項目設為 1flex-grow 因子。 您可以賦予 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
根據預設,Flexbox 會將項目排入一列,並在開始時排列這些項目。開啟包裝功能後,系統會繼續建立資料列,讓子項繼續流動。
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。 開頭是委刊項,結尾處則是所有額外空間。

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。 否則您沒有可以散佈訊息的空間。

這次請使用 Flexbox 資料欄版面配置,嘗試不同的值。

在彈性線之間分配空間

使用包裝的彈性容器時,可能會有更多空間可以分配到交叉軸。 在這種情況下,您可以使用與 justify-content 相同的值 align-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-contentjustify-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。 可用空間取決於彈性容器的高度 彈性委刊項或彈性委刊項

align-self 的初始值為 stretch。 因此根據預設,列中的彈性項目會延伸至最高項目的高度。 如要變更這項設定,請在任何 Flex 項目中加入 align-self 屬性。

.container {
  display: flex;
}

.item1 {
  align-self: flex-start;
}

請使用下列任一值讓項目對齊:

  • flex-start
  • flex-end
  • center
  • stretch
  • baseline

請參閱 MDN 值的完整清單

下一個示範包含包含 flex-direction: row 的單一彈性項目委刊項。 最後一個項目定義彈性容器的高度。 第一個項目的 align-self 屬性的值為 flex-start。 請嘗試變更該屬性的值,查看該屬性值在交叉軸上的移動方式。

align-self 屬性會套用至個別項目。 align-items 屬性可套用至 Flex 容器 將所有個別 align-self 屬性設為群組。

.container {
  display: flex;
  align-items: flex-start;
}

在下一項示範中,請嘗試變更 align-items 的值,讓交叉線之間的所有項目保持一致 整理成一個軸

為什麼 Flexbox 中沒有與自己有關的正當性?

Flex 項目會在主軸上作為一組群組。 所以並沒有將個別項目移出該群組的概念。

在格狀版面配置中,justify-selfjustify-items 屬性可在內嵌軸上運作 讓項目在網格區域內對齊 由於彈性版面配置會將項目視為群組 這些屬性不會在彈性環境中實作。

值得注意的是,Flexbox 與自動邊界功能非常相輔相成。 如果您發現需要將某個項目從群組中區分開來 或將群組分成兩個群組 即可套用邊界 在以下範例中,最後一個項目的左邊界為 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,即可移除預設延展值,改用內容高度。

資源