CSS Flexbox 完整教學 2026:一次搞懂彈性排版的核心概念
快速解答
Flexbox 是 CSS 的彈性排版系統,只要對父元素加上 `display: flex`,子元素就能自動彈性排列。用 `justify-content` 控制水平分布,`align-items` 控制垂直對齊,幾行 CSS 就能搞定大部分排版難題。
為什麼 Flexbox 是現代排版的首選?
還記得用 float 排版的年代嗎?浮動完還要清除浮動(clearfix),垂直置中要算負 margin,等高欄位甚至要用 JavaScript 計算……那個年代真的不好過。
CSS Flexbox 的出現改變了這一切。
過去的排版痛苦:
- 垂直置中:
position: absolute+transform: translateY(-50%)這種奇怪寫法 - 等高欄位:需要 JavaScript 動態計算每個欄位的高度
- 水平均分:
float+ 百分比寬度,小數點誤差容易讓最後一個元素掉下去 - 調整元素順序:只能修改 HTML 結構
Flexbox 的解法(只要幾行):
/* 水平 + 垂直置中,過去要寫 10 行,現在 3 行 */
.container {
display: flex;
justify-content: center; /* 水平置中 */
align-items: center; /* 垂直置中 */
}現在連垂直置中這個千年難題都能輕鬆解決。
目前所有主流瀏覽器都支援 Flexbox,你可以放心在任何專案中使用。如果你的網站也需要在不同裝置上完美呈現,記得搭配RWD響應式設計一起學習。
兩個核心角色:Container 與 Item
學 Flexbox 最重要的一件事:它分成兩個層級,Container 管控全局,Item 接受指令並可以有自己的彈性。
Container(容器)— 指揮官
.container {
display: flex; /* 宣告:我是 flex 容器! */
}加上 display: flex 的元素就是 Container,負責決定子元素怎麼排列、要不要換行、間距怎麼分配。
Item(項目)— 士兵
/* Container 的直接子元素,自動成為 Item */
<div class="container">
<div>Item 1</div> ← flex item
<div>Item 2</div> ← flex item
<div>Item 3</div> ← flex item
</div>注意:只有直接子元素才是 flex item,孫元素不受影響。
主軸與交叉軸
Flexbox 的排列由兩條軸線決定,這是理解所有屬性的關鍵:
- 主軸(Main Axis):flex item 排列的方向
- 交叉軸(Cross Axis):垂直於主軸的方向
/* 預設:主軸水平(→),交叉軸垂直(↓) */
.container { flex-direction: row; }
/* 改為:主軸垂直(↓),交叉軸水平(→) */
.container { flex-direction: column; }justify-content 永遠控制主軸,align-items 永遠控制交叉軸,記住這個規則就不會搞混。
Container 六大必學屬性
1. flex-direction(主軸方向)
flex-direction: row; /* → 水平排列(預設) */
flex-direction: row-reverse; /* ← 反向水平排列 */
flex-direction: column; /* ↓ 垂直排列 */
flex-direction: column-reverse; /* ↑ 反向垂直排列 */2. justify-content(主軸分布)
控制 item 在主軸上如何分布,是最常用的屬性之一:
justify-content: flex-start; /* 靠起點對齊(預設) */
justify-content: flex-end; /* 靠終點對齊 */
justify-content: center; /* 置中 */
justify-content: space-between; /* 兩端對齊,中間間距均分 */
justify-content: space-around; /* 每個 item 兩側間距相等 */
justify-content: space-evenly; /* 所有間距完全相等 */點下方按鈕看實際效果:
justify-content 互動對比
目前值:flex-start
3. align-items(交叉軸對齊)
控制 item 在交叉軸(垂直方向)的對齊方式:
align-items: stretch; /* 撐滿交叉軸(預設) */
align-items: flex-start; /* 靠起點對齊 */
align-items: flex-end; /* 靠終點對齊 */
align-items: center; /* 置中 */
align-items: baseline; /* 文字基線對齊 */4. flex-wrap(換行設定)
flex-wrap: nowrap; /* 不換行,item 超出容器會被壓縮(預設) */
flex-wrap: wrap; /* 超出容器寬度就自動換行 */5. gap(間距)
比 margin 更乾淨的間距寫法,只在 item 之間產生間距,不影響容器邊緣:
gap: 1rem; /* row 和 column 間距都是 1rem */
gap: 1rem 2rem; /* row-gap: 1rem, column-gap: 2rem */6. flex-flow(簡寫)
flex-direction + flex-wrap 的合體:
flex-flow: row wrap; /* 最常用:水平排列 + 允許換行 */
flex-flow: column nowrap; /* 垂直排列 + 不換行 */ Item 屬性:讓子元素控制自己的彈性
Container 屬性管全局,Item 屬性則讓個別子元素自主調整大小與對齊。
flex-grow(彈性放大)
數字代表「搶剩餘空間的比例」,0 代表不搶:
.item-a { flex-grow: 1; } /* 搶 1 份 */
.item-b { flex-grow: 2; } /* 搶 2 份(是 a 的兩倍) */
.item-c { flex-grow: 0; } /* 不搶,維持原本大小 */flex-shrink(彈性縮小)
容器不夠大時,item 縮小的比例,0 代表不縮小:
.item { flex-shrink: 1; } /* 預設,會依比例縮小 */
.item { flex-shrink: 0; } /* 不縮小,就算超出容器也不壓縮 */圖片、Logo 通常設定 flex-shrink: 0,避免被壓扁。
flex-basis(基礎大小)
item 在分配剩餘空間前的初始大小:
.item { flex-basis: 200px; } /* 初始寬度 200px */
.item { flex-basis: auto; } /* 由內容決定(預設) */
.item { flex-basis: 0; } /* 忽略內容大小,從 0 開始計算 */flex(三者的簡寫)
最推薦的寫法,同時設定 grow / shrink / basis:
.item { flex: 1; } /* = flex: 1 1 0%,均分剩餘空間 */
.item { flex: auto; } /* = flex: 1 1 auto */
.item { flex: none; } /* = flex: 0 0 auto,固定大小 */
.item { flex: 0 0 200px; } /* 固定 200px,不放大不縮小 */flex: 1 是做等寬欄位最常用的寫法,記起來!
align-self(單個 item 的對齊覆蓋)
覆蓋 container 的 align-items,只影響自己:
.special {
align-self: flex-end; /* 只有這個 item 靠底部 */
}order(排列順序)
數字越小越排前面,預設都是 0:
.item { order: -1; } /* 強制排最前面 */
.item { order: 2; } /* 排到後面 */ 實戰:三個最常見的排版場景
場景一:垂直 + 水平置中(最常用)
.center-box {
display: flex;
justify-content: center; /* 水平 */
align-items: center; /* 垂直 */
height: 200px;
}Flexbox 置中效果
場景二:導覽列(Logo 左、連結右)
.navbar {
display: flex;
justify-content: space-between; /* Logo 靠左,按鈕靠右 */
align-items: center;
padding: 0 1.5rem;
} 場景三:等高卡片排版
不管卡片內容多少,align-items: stretch(預設值)讓所有卡片高度自動對齊:
.cards {
display: flex;
gap: 1rem;
}
.card {
flex: 1; /* 均分寬度 */
/* 高度由 stretch 預設值自動等高 */
}等高卡片排版
注意三張卡片高度完全一致,這就是 align-items: stretch 的效果——讓所有 item 撐滿容器高度。
常見問題解答
Q:flex: 1 和 width: 100% 有什麼差別?
A: flex: 1 是「分配剩餘空間的比例」,多個 item 設定後會共享空間;width: 100% 是「佔父容器全寬」,多個 item 都設定的話會疊在一起(除非搭配 flex-wrap: wrap)。
想要等寬欄位,用 flex: 1;想要某個 item 獨佔一整行,用 flex-basis: 100% 或 width: 100%。
Q:justify-content 沒有效果?
A: 確認這三點:
- 父元素是否有
display: flex - 容器寬度是否足夠(如果 item 已經佔滿容器,就沒有剩餘空間可分配)
- item 是否設定了
flex-grow: 1(會搶光剩餘空間,讓 justify-content 無效)
Q:Flexbox vs CSS Grid,我該用哪個?
A: 兩者不衝突,看場景選擇:
- Flexbox:一個方向的排列(行 or 列),適合導覽列、按鈕群組、一排卡片
- CSS Grid:同時控制行 and 列,適合整頁版型、複雜的二維排版
實務上通常混搭:用 Grid 做頁面整體結構,用 Flexbox 做元件內部排列。
Q:手機版想改成垂直排列怎麼做?
A: 搭配 media query 改變 flex-direction:
.container {
display: flex;
gap: 1rem;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
} Flexbox 屬性速查表
Container 屬性
| 屬性 | 常用值 | 說明 |
|---|---|---|
display | flex | 啟用 Flexbox |
flex-direction | row / column | 主軸方向 |
justify-content | center / space-between / space-evenly | 主軸分布 |
align-items | center / stretch / flex-end | 交叉軸對齊 |
flex-wrap | wrap / nowrap | 是否換行 |
gap | 1rem | item 間距 |
flex-flow | row wrap | direction + wrap 簡寫 |
Item 屬性
| 屬性 | 常用值 | 說明 |
|---|---|---|
flex | 1 / none / 0 0 200px | grow + shrink + basis 簡寫 |
flex-grow | 0 / 1 | 放大比例 |
flex-shrink | 0 / 1 | 縮小比例 |
flex-basis | auto / 200px | 基礎大小 |
align-self | center / flex-end | 覆蓋單個 item 的對齊方式 |
order | 數字 | 排列順序,越小越前面 |
最常用的三個組合,背起來:
/* 垂直水平置中 */
display: flex;
justify-content: center;
align-items: center;
/* Navbar:Logo 左,按鈕右 */
display: flex;
justify-content: space-between;
align-items: center;
/* 等寬卡片排版 */
display: flex;
gap: 1rem;
.card { flex: 1; }掌握 Flexbox 之後,下一步可以學CSS Grid來處理二維排版,或者深入了解RWD響應式設計,讓排版在手機、平板、桌機上都完美顯示。