
結論先講
Grid 是專門為二維佈局設計的(列 + 行同時對齊)。跟 Flexbox 的分工:
| 場景 | 用 Flexbox | 用 Grid |
|---|---|---|
| 一排元素排列(導覽、tab) | ✅ | — |
| 單一方向的動態列表 | ✅ | — |
| 頁面主結構(header/nav/main/aside/footer) | — | ✅ |
| Dashboard 網格卡片 | — | ✅ |
| 雜誌式版面(跨列跨行) | — | ✅ |
| 簡單的兩欄佈局 | 都可以 | 都可以 |
一個判斷:你需要同時控制「第 X 列第 Y 行」的位置 → Grid。只控制一個方向 → Flexbox。
心智模型:畫格子
.container {
display: grid;
grid-template-columns: 200px 1fr 100px; /* 三欄:固定、彈性、固定 */
grid-template-rows: 80px 1fr 60px; /* 三列:固定、彈性、固定 */
gap: 16px;
}產生這樣的格子:
┌─────────┬──────────────────┬────────┐
│ 80px │ │ │
├─────────┼──────────────────┼────────┤
│ │ │ │
│ 1fr │ │ │
│ │ │ │
├─────────┼──────────────────┼────────┤
│ 60px │ │ │
└─────────┴──────────────────┴────────┘
200px 1fr 100px
子元素自動按順序填進格子。
fr 單位:彈性分配
fr = fraction(份)。分配剩餘空間:
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 1:2:1 分配 */
}假設容器寬 400px,間距 0:
- 第一欄:100px(1/4)
- 第二欄:200px(2/4)
- 第三欄:100px(1/4)
混用固定跟彈性
grid-template-columns: 250px 1fr 1fr;第一欄固定 250px(側欄),剩下空間兩欄平均分。
命名網格區域:grid-template-areas
最容易讀的寫法:
.layout {
display: grid;
grid-template-columns: 200px 1fr 150px;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 16px;
}
.layout > header { grid-area: header; }
.layout > nav { grid-area: nav; }
.layout > main { grid-area: main; }
.layout > aside { grid-area: aside; }
.layout > footer { grid-area: footer; }HTML:
<div class="layout">
<header>...</header>
<nav>...</nav>
<main>...</main>
<aside>...</aside>
<footer>...</footer>
</div>網格 template 就是 ASCII 排版圖。新人讀 code 秒懂。
響應式:在 media query 改 template-areas
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
}整個版面重排,不用改 HTML。
repeat() + minmax():響應式網格的神器
固定欄數
grid-template-columns: repeat(4, 1fr);
/* 等同 1fr 1fr 1fr 1fr */最小寬度 + 自動欄數
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));解讀:每欄最小 250px、最大 1fr(平均分)、空間夠就自動多一欄。
不用 media query 就能響應式:
寬 1200px → 4 欄(每欄 300px)
寬 900px → 3 欄(每欄 300px)
寬 600px → 2 欄(每欄 300px)
寬 300px → 1 欄(占滿)
auto-fit vs auto-fill
auto-fit:空欄被摺疊(可用空間給 item 撐大)auto-fill:空欄保留(留白)
99% 情況你要的是 auto-fit。
跨格子:grid-column / grid-row
讓單一元素跨多格:
.hero {
grid-column: 1 / 4; /* 從第 1 條線到第 4 條線,跨 3 欄 */
grid-row: 1 / 3; /* 跨 2 列 */
}
/* 或用 span */
.hero {
grid-column: span 3;
grid-row: span 2;
}線的編號
1 2 3 4
│ │ │ │
├────┼────┼────┤ 1
│ │ │ │
├────┼────┼────┤ 2
│ │ │ │
├────┼────┼────┤ 3
線永遠比欄/列多 1 條。
對齊屬性(跟 Flexbox 類似但有新玩意)
| 屬性 | 作用 | 放哪 |
|---|---|---|
justify-content | 整個網格在容器水平位置(容器有剩餘空間時) | 容器 |
align-content | 整個網格在容器垂直位置 | 容器 |
justify-items | 每個 item 在自己格子裡的水平對齊 | 容器 |
align-items | 每個 item 在自己格子裡的垂直對齊 | 容器 |
justify-self / align-self | 單一 item 的對齊 | item |
place-items: center | 速記:justify-items + align-items | 容器 |
place-content: center | 速記:justify-content + align-content | 容器 |
超簡單置中
.container {
display: grid;
place-items: center;
min-height: 100vh;
}一行搞定。Flexbox 還要兩行。
常見模式:3 個 Pattern
Pattern 1:Holy Grail Layout(聖杯佈局)
.layout {
display: grid;
grid-template: auto 1fr auto / 200px 1fr 150px;
min-height: 100vh;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}Pattern 2:響應式卡片網格
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}Pattern 3:儀表板(Dashboard)
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr); /* 12 欄系統 */
gap: 16px;
}
.stat-card { grid-column: span 3; } /* 每張卡 3 欄 */
.chart-wide { grid-column: span 6; } /* 寬圖表 6 欄 */
.chart-full { grid-column: 1 / -1; } /* 滿寬 */1 / -1 = 從第 1 條線到最後一條(反向索引)。
Subgrid:讓子元素對齊父網格
CSS Grid Level 2 的新功能(Chrome 117+、Firefox 71+、Safari 16+):
.parent {
display: grid;
grid-template-columns: 200px 1fr 150px;
}
.child {
grid-column: 1 / 4;
display: grid;
grid-template-columns: subgrid; /* 繼承父網格的欄位 */
}以前要用 flex + 各種 calc 才能做到的「巢狀對齊」,subgrid 直接搞定。
常見陷阱
陷阱 1:item 內容超出格子
.item {
min-width: 0;
overflow: hidden;
}跟 Flexbox 一樣,內容太長會撐破格子。
陷阱 2:auto 列高跟 1fr 的差別
grid-template-rows: auto 1fr auto;auto:按內容高度1fr:吃剩餘空間
陷阱 3:grid 速記屬性容易搞混
grid: auto 1fr auto / 200px 1fr 150px;
/* ↑ rows ↑ columns *// 前是列,/ 後是欄。順序不能反。
實戰 Checklist
- 頁面主結構用 Grid(不用多層 Flexbox)
- 響應式卡片用
repeat(auto-fit, minmax(Xpx, 1fr)) - 用
grid-template-areas讓版面圖直接在 CSS 可讀 -
gap管間距 - 置中用
place-items: center - 超出邊界用
min-width: 0加overflow: hidden
相關文章
- Flexbox 一維佈局 — 互補關係
- Box Model — 基礎
- CSS 子 Roadmap
- Frontend Roadmap