CSS Grid 與 Flexbox:何時該用哪一個?
為什麼 Grid 與 Flexbox 之爭總是被提起
你正在建立一個版面。你習慣性地拿起 Flexbox,但做到一半卻發現自己在跟瀏覽器對抗:嵌套的容器、百分比寬度,還有彆扭的對齊技巧。與此同時,隊友堅持 CSS Grid 只要三行就能解決。這兩個工具都很強大,但它們解決的是不同的問題。選錯工具會導致脆弱的 CSS 和浪費的時間。
本指南將帶你釐清混亂。你將學到 CSS Grid 和 Flexbox 的核心心智模型,看到並排比較,並獲得一份可以立即套用的實用決策清單。
核心心智模型
Flexbox 是一維的。它沿著單一軸線(列或欄)排列項目並分配空間。把它想像成一條可以換行的彈性線。Grid 是二維的。它同時定義列和欄,讓你能將項目放入精確的矩陣中。把它想像成你頁面的試算表。
兩者都沒有「更好」。它們是互補的。大多數真實世界的版面會同時使用兩者:Grid 用於整體頁面骨架,Flexbox 用於較小的元件,例如導覽列或按鈕群組。
何時使用 Flexbox
當你的版面主要朝一個方向流動,且內容大小應該驅動版面時,就選擇 Flexbox。常見情境:
- 導覽列:一行連結,應該平均分散,或將標誌推到左邊、選單推到右邊。
- 卡片內容:在卡片內垂直對齊圖示、標題和說明。
- 按鈕群組:一組間距一致的按鈕。
- 置中單一元素:經典的
display: flex; justify-content: center; align-items: center;。 - 動態內容:當你不知道會有多少項目,並希望它們自然換行時。
Flexbox 擅長分配剩餘空間,以及讓項目彼此相對對齊。它是內容優先:項目決定容器的大小。
何時使用 CSS Grid
當你需要同時控制列和欄,或想將項目放入特定區域而不受 HTML 順序影響時,就選擇 Grid。理想的使用情境:
- 頁面層級版面:頁首、側邊欄、主內容、頁尾以範本方式排列。
- 複雜的卡片網格:某些卡片跨兩欄或兩列的藝廊。
- 重疊元素:使用同一個網格儲存格將項目疊放在一起。
- 一致的間距:使用
gap統一隔開列和欄。 - 無需媒體查詢的響應式:
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));用一行就能建立響應式網格。
Grid 是版面優先:你定義結構,項目被放入其中。這讓它非常適合整體頁面架構。
CSS Grid 與 Flexbox:快速比較
| 功能 | Flexbox | CSS Grid |
|---|---|---|
| 維度 | 一維(列或欄) | 二維(列和欄) |
| 方法 | 內容優先 | 版面優先 |
| 項目放置 | 基於流動,順序可變 | 明確放置在儲存格中 |
| 換行 | flex-wrap | 透過網格軌道隱含 |
| 間距支援 | 是(現代瀏覽器) | 是 |
| 最適合 | 元件、工具列、置中 | 頁面版面、複雜網格 |
如何有效結合兩者
真正的威力在於將一個嵌套在另一個裡面。典型模式:
- 使用 Grid 處理主要頁面區域:頁首、側邊欄、主內容、頁尾。
- 在頁首內,使用 Flexbox 對齊標誌和導覽連結。
- 在主內容區域內,使用 Grid 建立卡片藝廊。
- 在每張卡片內,使用 Flexbox 垂直排列圖片、標題和文字。
這種混合方法讓你的 CSS 保持模組化,並避免過度設計。你在需要的地方獲得 Grid 的結構控制,並為較小的部分獲得 Flexbox 的靈活對齊。
實用程式碼範例
Flexbox:導覽列
.nav {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
Grid:響應式卡片藝廊
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
這一行就能處理任何螢幕尺寸,無需媒體查詢。Flexbox 無法如此簡潔地做到,因為它缺少欄的定義。
Grid:具名區域的頁面版面
.page {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
具名區域讓版面自我說明。重新排列頁面變成只要編輯範本字串。
常見陷阱與避免方法
- 用 Flexbox 做二維版面:你最終會得到嵌套的 flex 容器和百分比寬度。改用 Grid。
- 用 Grid 做簡單的一行項目:可行,但對於未知內容大小,Flexbox 通常更簡單且更有彈性。
- 忘記在 flex 項目上設定
min-width: 0:防止長文字或圖片造成溢出問題。 - 過度使用
order:改變視覺順序而不更新 DOM 順序會損害無障礙性。盡可能改用 Grid 放置。 - 忽略
gap:Grid 和 Flexbox 都支援gap,可消除 margin 技巧。
決策清單:你該用哪一個?
問自己這些問題:
- 版面需要同時控制列和欄嗎?→ Grid。
- 內容朝一個方向流動,且大小應由內容驅動嗎?→ Flexbox。
- 你需要將項目放在特定區域或重疊它們嗎?→ Grid。
- 你是在容器內對齊幾個項目嗎?→ Flexbox。
- 你想要無需媒體查詢的響應式網格嗎?→ 使用
auto-fit的 Grid。
如果你仍不確定,元件先用 Flexbox,頁面用 Grid。你隨時可以之後重構。
常見問題
我可以同時使用 CSS Grid 和 Flexbox 嗎?
當然可以。它們的設計就是互補的。使用 Grid 處理整體頁面結構,Flexbox 處理較小的元件,例如導覽列、工具列和卡片內容。
有了 Grid,Flexbox 就過時了嗎?
不。Flexbox 仍然是一維版面和內容驅動尺寸的最佳選擇。Grid 不是替代品,而是二維版面的額外工具。
哪個瀏覽器支援更好?
兩者在所有現代瀏覽器都支援,包括 Chrome、Firefox、Safari 和 Edge。對於非常舊的瀏覽器,你可能需要備用方案,但對今天大多數專案而言,你可以放心使用任一個。
準備好快速測試你的版面想法了嗎?使用我們的 HTML 轉圖片轉換器,將你的 HTML/CSS 模型變成可分享的圖片,用於設計審查或文件說明。