
結論先講
Flexbox 處理一維佈局(單一軸向排列)。一維的定義:你只在一個方向上分配空間。
✅ 適合 Flexbox:
- 導覽列(一排項目橫向排)
- 卡片列(單排卡片)
- 水平/垂直置中
- 表單行(label + input)
- 分散對齊(左右兩邊的元素)
❌ 不適合 Flexbox(該用 Grid):
- 二維表格(列 + 行同時對齊)
- 雜誌式版面
- Dashboard 網格
搞清楚這條界線就不會硬 flex 所有東西。
心智模型:容器 + 項目
Flexbox 有兩個角色:
<div class="container"> <!-- display: flex -->
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>- Flex 容器:
display: flex的元素 - Flex 項目:容器的直接子元素
不是所有屬性都放在容器,也不是所有屬性都放在項目:
| 放容器 | 放項目 |
|---|---|
flex-direction | flex-grow |
flex-wrap | flex-shrink |
justify-content | flex-basis |
align-items | align-self |
gap | order |
兩條軸:主軸 & 交叉軸
Flexbox 有兩條軸,決定所有對齊屬性的方向:
flex-direction: row(預設)
┌──────────────────────────────┐
│ → → 主軸(main axis)→ → │
│ │
│ ↓ 交叉軸(cross axis)↓ │
└──────────────────────────────┘
flex-direction: column
┌──────────────────────────────┐
│ ↓ 主軸 │
│ ↓ │
│ → 交叉軸 │
└──────────────────────────────┘
重要:主軸跟交叉軸會互換。justify-content 永遠沿主軸,align-items 永遠沿交叉軸。
justify-content(主軸分配)
.container { display: flex; justify-content: <value>; }| 值 | 效果 |
|---|---|
flex-start(預設) | 從起點緊靠排 |
flex-end | 從終點緊靠排 |
center | 置中 |
space-between | 兩端對齊,中間平均 |
space-around | 每項左右等距 |
space-evenly | 所有間距相等(含邊) |
視覺對照
[A] [B] [C] flex-start
[A] [B] [C] flex-end
[A] [B] [C] center
[A] [B] [C] space-between
[A] [B] [C] space-around
[A] [B] [C] space-evenly
align-items(交叉軸對齊)
.container { display: flex; align-items: <value>; }| 值 | 效果 |
|---|---|
stretch(預設) | 拉伸填滿交叉軸 |
flex-start | 頂部對齊 |
flex-end | 底部對齊 |
center | 垂直置中 |
baseline | 文字基線對齊 |
最常用的:垂直水平雙置中
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}CSS 界的「如何置中」折磨了 20 年,Flexbox 兩行解決。
flex 速記屬性(最多人搞不清楚)
每個 item 可以設 flex: X Y Z,三個值:
.item { flex: <grow> <shrink> <basis>; }flex-grow(預設 0):有多餘空間時,這項佔比多少flex-shrink(預設 1):空間不夠時,這項縮多少flex-basis(預設 auto):起始大小
常見組合
.item { flex: 1; }
/* 等同 flex: 1 1 0% — 平均分配可用空間 */
.item { flex: 0 0 200px; }
/* 固定 200px,不長不縮 */
.item { flex: 1 0 auto; }
/* 按內容起始,有空間就吃,不縮小 */
.item { flex: auto; }
/* 等同 flex: 1 1 auto — 跟內容走但可彈性 */實戰建議:99% 情況你要的是 flex: 1(平均)或 flex: 0 0 Xpx(固定尺寸)。
gap:間距的最佳解法
.container {
display: flex;
gap: 16px; /* 項目之間的間距 */
}不要用 margin 噴間距:
❌ 壞:
.item { margin-right: 16px; }
.item:last-child { margin-right: 0; } /* 最後一個要單獨處理 */✅ 好:
.container { display: flex; gap: 16px; }gap 自動處理「只在中間出現間距」的邏輯,還相容 flex-wrap。
flex-wrap:換行
.container {
display: flex;
flex-wrap: wrap; /* 空間不夠就換行 */
gap: 16px;
}配合 flex-basis 做響應式卡片:
.card {
flex: 1 1 300px; /* 最小 300px,可長可縮 */
}空間夠時卡片一排 3 張,縮小時自動變 2 張、1 張。不用 media query。
常見陷阱
陷阱 1:子元素的 width 被忽略
.container { display: flex; }
.item { width: 200px; }如果容器設 flex-grow,width 可能被壓縮。用 flex: 0 0 200px 替代。
陷阱 2:文字溢出容器
Flex 項目預設 min-width: auto(不是 0)。長文字會把容器撐大:
.item {
min-width: 0; /* 關鍵 */
overflow: hidden;
text-overflow: ellipsis;
}陷阱 3:垂直 Flex 容器需要明確高度
.container {
display: flex;
flex-direction: column;
height: 100vh; /* 沒設高度,align-items 沒意義 */
}陷阱 4:flex: 1 不一定等高
.container { display: flex; }
.item { flex: 1; }所有 item 寬度相等(因為 flex-grow: 1)但 flex-basis: 0,所以內容不同時高度不一致。要等高設 align-items: stretch(這是預設,但如果被覆寫要明確設)。
什麼時候該切到 Grid
Flexbox 做得很辛苦的情境
┌────────────────────────────────┐
│ Header │
├─────┬──────────────────┬───────┤
│ Nav │ Main │ Aside │
│ │ │ │
├─────┴──────────────────┴───────┤
│ Footer │
└────────────────────────────────┘
這種「列 + 行同時對齊」的版面用 Flexbox 要多層巢狀 + 各種 flex 調整,很快會混亂。
切 Grid。 一個容器就搞定。下一篇講。
實戰 Checklist
- 只用 Flexbox 做一維排列(單方向)
- 二維版面(列+行同時對齊)切到 Grid
- 用
gap管間距,不要用 margin - 垂直置中用
justify-content + align-items - 動態寬度元素用
flex: 1,固定尺寸用flex: 0 0 Xpx - 長文字項目加
min-width: 0; overflow: hidden;
工具:DevTools 的 Flexbox Inspector
Chrome/Firefox DevTools 對 flex 容器的元素會顯示 flex badge。點開能視覺化看主軸、交叉軸、間距分配。debug 必備。
相關文章
- CSS 子 Roadmap
- CSS Box Model — 先搞懂 box
- 下一篇 → Grid 二維佈局(🌱)
- Frontend Roadmap
