CSS Flexbox 佈局教學,附實用排版測試工具

Feature image for CSS Flexbox 佈局教學,附實用排版測試工具

看完本文,你會學到足夠使用的 CSS Flexbox 技術。文章內提供的排版測試工具,可以幫助你理解 Flexbox 的工作原理,並快速實驗不同的屬性和想法。

1. Flexbox 是什麼

2. Flexbox 排版測試

3. Flexbox 基本概念

4. Flexbox 常用屬性

5. Flexbox 與其他 CSS 佈局技術的比較

6. 延伸學習

7. 常見問題

Flexbox 是什麼

Flexbox 是一種 CSS 佈局模式。那麼,還有什麼其他佈局模式呢?

  • 一般佈局 (Normal Flow)
  • 表格佈局 (Table layout)
  • 定位佈局 (Positioned layout)
  • 多欄位佈局 (Multi-column layout)
  • 彈性佈局 (Flexible box layout)
  • 網格佈局 (Grid layout)

CSS Flexbox 其實比其他佈局模式簡單。一開始接觸可能會覺得很複雜,但在了解基本概念後,就會發現比使用傳統的定位佈局簡單很多。

尤其當你要設計自適應網頁 (Responsive Web Design) 時,Flexbox 的彈性,真的會減少很多麻煩。

Flexible Box Layout 的佈局規範雖然仍在持續演進中,但大多數主流瀏覽器都已經實作 Flexbox 功能,基本上可以安心使用,不用擔心瀏覽器的相容性問題(除了已停止支援的 IE)。

img src: caniuse.com

Flexbox 排版測試

Flexbox 基本概念

img src: drafts.csswg.org

Flexbox 主要有兩個核心概念需要了解:一個是 Flex Container(彈性容器),另一個是 Flex Items(彈性項目)。

首先,需要理解主軸(main axis)和交叉軸(cross axis)的區別。主軸是 flex items 排列的主要方向,交叉軸則與主軸垂直。

Flex Container 會建立一個 flex 格式空間,在容器中的元件就是 Flex Items。需要注意的是,只有第一層的直接子元件才會成為 Flex Items。

<div class="container">
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
</div>

Flex 子元件會忽略 float 設定,還可以透過 order 屬性設定顯示順序,這讓佈局控制更加靈活方便。

Flexbox 常用屬性

以下僅列出一般常用的屬性,不包含簡寫屬性和細項控制屬性。

flex container 屬性

絕大多數的 flex 屬性,都是設定在 container 身上,而設定後的效果是套用在全部的 items 身上。

display

display 可設定為 flexinline-flex。設定 flex 會建立一個區塊級的 flex 格式空間,而 inline-flex 則會建立一個行內級的 flex 格式空間。

.container {
    display: flex | flex-inline; 
}

flex-direction

flex-direction 用來設定子項目(flex items)的佈局流向,可以設定為由左到右、由右到左、由上到下或由下到上。

.container {
    flex-direction: row | row-reverse | column | column-reverse;
}

flex-wrap

當子項目的數量很多,超過容器的可用空間時,flex-wrap 可以控制是否要自動換行。

.container { 
    flex-wrap: nowrap | wrap | wrap-reverse; 
}

justify-content

justify-content 可以設定 flex items 沿著主軸排列的方式。

.container { 
    justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right; 
}

align-items

align-items 可以設定 flex items 沿著交叉軸(cross axis)排列的方式。

.container { 
    align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end; 
}

align-content

align-content 只有在 flex items 多行(即 flex-wrap: wrap 且有多行內容)的狀況下才會產生作用,用來控制多行之間的對齊方式。

.container { align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline}

row-gap

row-gap 控制 flex items 之間的行間距(上下間隔)。

.container { 
    row-gap: 10px; 
}

column-gap

column-gap 控制 flex items 之間的列間距(左右間隔)。

.container { 
    column-gap: 10px; 
}

flex item 屬性

Container 屬性是比較全局的設定,會影響所有子項目。如果需要對個別項目進行控制,就使用 item 屬性。

可以將所有 item 屬性都設定為相同的值,也可以針對不同的項目進行個別設定。

flex-grow

flex-grow 設定彈性增長因子,用來控制當容器有剩餘空間時,項目如何分配這些空間。設定為 1 時,flex item 會自動增長以填滿剩餘空間。預設值是 0,表示不會自動增長。

.item { 
    flex-grow: 1; 
}

flex-shrink

flex-shrink 設定彈性縮減因子,用來控制當容器空間不足時,項目如何縮小。設定為 1 時,flex item 會自動縮減以適應容器大小。預設值是 1,表示可以縮減。

.item { 
    flex-shrink: 0; 
}

flex-basis

flex-basis 設定 flex item 的初始大小,可以設定為具體的長度值(如 200px50% 等),預設值是 auto。這個屬性會影響項目在分配剩餘空間之前的基礎大小。

參考 Mozilla 的 flex-basis 說明。

.item { 
    flex-basis: <length> | auto; /* default auto */ 
}

flex

flexflex-growflex-shrinkflex-basis 三個屬性的簡寫。

設定格式為:

.item {
    flex:  none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ];
}

Flexible Box Layout 規格書中建議應該使用 flex 簡寫屬性,而不是直接使用 flex-growflex-shrinkflex-basis 來控制,因為簡寫會正確重置任何未指定的組件,以適應常見的使用情境。

常用的設定有:

  • flex: 1 1 0%;
  • flex: 1 1 auto;
  • flex: 0 1 auto;
  • flex: none;

設定 none 時,表示 ‘flex: 0 0 auto’。

TailwindCSS 就是使用上列 4 種設定。

Flexbox 與其他 CSS 佈局技術的比較

先簡單說明幾個不同的佈局技術:

  1. Flexbox(彈性盒子):就像是一條單行的火車,你可以很容易地讓火車車廂(也就是網頁上的元素)排列得整整齊齊,或者讓它們自動填滿空間。但是,如果你想要建立一個複雜的火車站(二維佈局),那就不太適合。
  2. Grid(網格):這就像是一個棋盤,你可以在橫向和縱向都很容易地放置棋子(網頁元素)。但如果你只需要一行或一列,這可能會有點過度。
  3. Float(浮動):這是一種老式的方法,就像是把書放在書架上,但有時你需要自己去整理它們,以免它們亂掉。這個方法在所有的瀏覽器上都能運行得很好,但有時會讓人頭痛。
  4. Positioning(定位):這就像是在一個空房間裡,你可以把家具(網頁元素)放在你想要的任何地方,但你需要自己量尺寸和位置,這可能會花更多的時間。
佈局技術優點缺點最適用場景
Flexbox1. 更適合一維佈局
2. 自動計算和調整元素大小
1. 不支持老舊瀏覽器
2. 不適用於複雜的二維佈局
一維佈局,動態元素大小調整
Grid1. 適用於二維佈局
2. 容易控制行和列
過於複雜對於一維佈局複雜的二維佈局
Float1. 廣泛的瀏覽器支持
2. 適用於簡單佈局
1. 需要手動清除浮動
2. 佈局可能更複雜
簡單佈局,老舊瀏覽器支持
Positioning1. 完全自由的佈局控制
2. 高度自定義
1. 需要手動計算和設置元素位置
2. 可能更耗時
高度自定義的佈局需求

延伸學習

A Complete Guide to Flexbox,CSS-Tricks 的教學很清楚,搭配圖解說明,直接看出效果不用花時間打字實驗,本文第二節的遊樂場就是依據 CSS-Tricks 教學開發的工具。

行事曆開發範例中,從月份到日期都使用 flex 來編排。

最詳細的說明當然在 Flexible Box Layout 規格書中

MDN 的 flex 布局基本概念 對基礎學習很有幫助。

FLEXBOX FROGGY,玩遊戲學 Flex。

常見問題

CSS FLEXBOX 是用來做什麼的?

FLEXBOX 是一種用來當作網頁佈局的 CSS 技術。

CSS FLEXBOX 和 CSS GRID 有什麼不同?

CSS FLEXBOX 主要用於單一方向(水平或垂直方向)的佈局,而 CSS GRID 則適用於整個平面的二維佈局。FLEXBOX 相對簡單一點,比較適合處理網頁內的區塊佈局;GRID 則比較適合用於整個網頁的整體設計佈局。

我應該學習 CSS FLEX 嗎?

當然啊,不要再用 Table 或是 Float 來設計網頁了。

如何將元素垂直和水平居中?

在 flex container 上同時將 justify-contentalign-items 屬性都設置為 center,即可將子元素垂直和水平居中。

如何改變 Flex item 的順序?

可以使用 order 屬性來改變 Flex item 的順序。數字越小,項目排列越前面。

如何使 Flex item占滿剩餘空間?

使用 flex-grow 屬性,設置為大於 0 的數字,使得 Flex item 可以根據該數字的比例來分配剩餘空間。

如何讓 Flex item 自動換行?

在 Flex 容器上使用 flex-wrap 屬性,並設置為 wrap 即可。

如何反轉 Flex 項目的排列方向?

使用 flex-direction 屬性並將其設置為 row-reverse(水平反轉)或 column-reverse(垂直反轉)即可。