跳轉到內容

CSS Grid 網格佈局從入門到實戰 2026 | 零基礎入門教程

CSS Grid 網格佈局從入門到實戰

學會了 Flexbox 之後,你可能會遇到更復雜的佈局需求:比如把頁面分成「頭部、側邊、內容、底部」四個區域,或者做一個相冊網格。這時候 CSS Grid 就登場了!Grid 是比 Flexbox 更強大的二維佈局系統,這篇教程繼續用大白話帶你從零掌握。


一、Grid 和 Flexbox 有什麼區別?

1.1 通俗對比

特性FlexboxGrid
維度一維(一行或一列)二維(行和列同時)
比喻排隊桌子擺盤子
適用場景導航欄、按鈕組、居中整頁佈局、相冊、表格
控制方式從內容出發從容器出發

大白話理解:

  • Flexbox 就像排隊——大家排成一行(或一列),重點是「排隊的方向」
  • Grid 就像在桌子上擺盤子——先畫好格子,再把盤子放到指定的格子裡

1.2 什麼時候用 Grid?

場景例子
整頁佈局頭部 + 側邊欄 + 內容 + 底部
圖片相冊3×3 的照片網格
表單佈局標籤和輸入框對齊
卡片網格商品列表、文章列表
儀表盤多個面板的複雜排列

1.3 最簡單的例子

html
<div class="grid">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
css
.grid {
  display: grid;
  grid-template-columns: 100px 100px 100px;  /* 3列,每列100px */
  grid-template-rows: 80px 80px;             /* 2行,每行80px */
  gap: 10px;                                 /* 間距10px */
}

.item {
  background: #4a90d9;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
}

效果: 6 個方塊自動排成了 3 列 2 行的網格,整齊又美觀!

┌───────┬───────┬───────┐
│   1   │   2   │   3   │
├───────┼───────┼───────┤
│   4   │   5   │   6   │
└───────┴───────┴───────┘

二、定義網格:行和列

2.1 grid-template-columns(定義列)

這是 Grid 中最重要的屬性,用來定義有多少列、每列多寬:

css
.grid {
  display: grid;

  /* 3列,每列100px */
  grid-template-columns: 100px 100px 100px;

  /* 2列,第一列200px,第二列300px */
  grid-template-columns: 200px 300px;

  /* 3列,每列相等(auto表示均分) */
  grid-template-columns: auto auto auto;
}

2.2 fr 單位(重點!)

fr 是 Grid 特有的單位,表示「按比例分配剩餘空間」,就像 Flexbox 的 flex-grow

css
.grid {
  display: grid;

  /* 3列等寬 */
  grid-template-columns: 1fr 1fr 1fr;
  /* 等價於 */
  grid-template-columns: repeat(3, 1fr);

  /* 第一列固定200px,剩餘空間按1:2分配 */
  grid-template-columns: 200px 1fr 2fr;

  /* 第一列按內容撐開,第二列佔1份,第三列佔2份 */
  grid-template-columns: auto 1fr 2fr;
}

💡 大白話fr 就是「份」。1fr 2fr 就是按 1:2 的比例分蛋糕。

2.3 repeat() 函數

當列數很多時,用 repeat() 更簡潔:

css
.grid {
  display: grid;

  /* 重複3次 1fr,等價於 1fr 1fr 1fr */
  grid-template-columns: repeat(3, 1fr);

  /* 重複4次 100px */
  grid-template-columns: repeat(4, 100px);

  /* 混合使用 */
  grid-template-columns: 200px repeat(3, 1fr) 100px;
}

2.4 auto-fit 和 auto-fill(自動列數)

這兩個值可以實現「自動響應式」,不需要寫媒體查詢!

css
.grid {
  display: grid;

  /* 自動適應:每列最少200px,放不下就換行 */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

這是 Grid 最強大的功能之一! 上面的代碼會:

  • 屏幕寬時,自動多放幾列
  • 屏幕窄時,自動減少列數
  • 每列最少 200px,剩餘空間均分

auto-fitauto-fill 的區別:

  • auto-fit:空的格子會塌縮,讓現有格子撐滿
  • auto-fill:保留空格子位置

💡 99% 的情況下用 auto-fit 就對了!

2.5 grid-template-rows(定義行)

grid-template-columns 類似,用來定義行的高度:

css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;

  /* 3行,第一行100px,第二行200px,第三行100px */
  grid-template-rows: 100px 200px 100px;

  /* 第一行按內容,第二行佔滿剩餘 */
  grid-template-rows: auto 1fr;
}

💡 大多數情況下,行高不需要手動定義,讓內容自動撐開就好。

2.6 gap(間距)

和 Flexbox 一樣,Grid 也可以用 gap 設置間距:

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);

  gap: 16px;           /* 行列間距都是16px */
  /* 或者分別設置 */
  row-gap: 20px;       /* 行間距 */
  column-gap: 16px;    /* 列間距 */
}

三、網格線(Grid Lines)

3.1 什麼是網格線?

Grid 會自動給每條線編號,從 1 開始:

  1       2       3       4
  │       │       │       │
1 ├───────┼───────┼───────┤
  │   1   │   2   │   3   │
2 ├───────┼───────┼───────┤
  │   4   │   5   │   6   │
3 └───────┴───────┴───────┘
  • 列線:1, 2, 3, 4(從左到右)
  • 行線:1, 2, 3(從上到下)

3.2 用網格線定位子元素

css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 100px 100px;
}

/* 把 A 放到第2列到第3列,第1行到第2行 */
.item-a {
  grid-column: 2 / 3;  /* 從第2條線到第3條線 */
  grid-row: 1 / 2;     /* 從第1條線到第2條線 */
}

/* 把 B 放到第1列到第3列(跨2列),第2行到第3行 */
.item-b {
  grid-column: 1 / 3;  /* 跨2列 */
  grid-row: 2 / 3;
}

💡 大白話grid-column: 2 / 4 意思是「從第 2 條線開始,到第 4 條線結束」,也就是佔了第 2 和第 3 兩列。

3.3 跨越的簡寫

css
/* 從第1列開始,跨3列 */
.item {
  grid-column: 1 / span 3;
  /* 等價於 */
  grid-column: 1 / 4;
}

/* 從當前位置開始,跨2列 */
.item {
  grid-column: span 2;
}

💡 記憶技巧span N 就是「跨越 N 個格子」。


四、網格區域(Grid Areas)

4.1 給區域命名

可以用名字來命名網格區域,非常直觀:

css
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
}

就像畫了一個表格:

┌──────────────────────────┐
│        header            │
├──────────┬───────────────┤
│ sidebar  │    content    │
├──────────┴───────────────┤
│        footer            │
└──────────────────────────┘

4.2 使用命名區域

css
.header {
  grid-area: header;
}

.sidebar {
  grid-area: sidebar;
}

.content {
  grid-area: content;
}

.footer {
  grid-area: footer;
}

💡 這是 Grid 最直觀的用法! 畫個「ASCII 圖」就能定義佈局,一目瞭然。

4.3 用點號表示空區域

css
.grid {
  grid-template-areas:
    "header  header  header"
    "sidebar .       content"
    "footer  footer  footer";
}

中間的 . 表示這個位置留空。

4.4 響應式佈局(改變區域排列)

css
.layout {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "header"
    "content"
    "sidebar"
    "footer";
}

/* 大屏幕改成左右佈局 */
@media (min-width: 768px) {
  .layout {
    grid-template-columns: 200px 1fr;
    grid-template-areas:
      "header  header"
      "sidebar content"
      "footer  footer";
  }
}

💡 超方便! 只需要改 grid-template-areas 就能切換佈局,HTML 完全不用動!


五、對齊方式

5.1 容器對齊(整體)

屬性作用類比 Flexbox
justify-items子元素在格子內的水平對齊無直接對應
align-items子元素在格子內的垂直對齊align-items
justify-content整個網格在容器內的水平位置justify-content
align-content整個網格在容器內的垂直位置align-content
css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  height: 400px;

  /* 每個格子內的子元素:水平居中 */
  justify-items: center;

  /* 每個格子內的子元素:垂直居中 */
  align-items: center;

  /* 整個網格水平居中 */
  justify-content: center;

  /* 整個網格垂直居中 */
  align-content: center;
}

5.2 子元素對齊(單獨)

css
.item {
  /* 單獨設置這個元素在格子內的水平對齊 */
  justify-self: start;  /* 或 center / end / stretch */

  /* 單獨設置這個元素在格子內的垂直對齊 */
  align-self: center;
}

5.3 對齊速查表

justify-*  = 水平方向(左右)
align-*    = 垂直方向(上下)
*-items    = 設置所有子元素
*-content  = 設置整體網格
*-self     = 設置單個子元素

六、實戰練習

6.1 練習一:經典網頁佈局

html
<div class="layout">
  <header class="header">頭部導航</header>
  <aside class="sidebar">側邊欄</aside>
  <main class="content">主要內容區</main>
  <footer class="footer">底部版權</footer>
</div>
css
.layout {
  display: grid;
  min-height: 100vh;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
}

.header {
  grid-area: header;
  background: #1a1a2e;
  color: white;
  display: flex;
  align-items: center;
  padding: 0 20px;
}

.sidebar {
  grid-area: sidebar;
  background: #16213e;
  color: white;
  padding: 20px;
}

.content {
  grid-area: content;
  background: #f5f5f5;
  padding: 24px;
}

.footer {
  grid-area: footer;
  background: #1a1a2e;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 響應式:小屏幕改成上下排列 */
@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
  }
}

6.2 練習二:響應式相冊

html
<div class="gallery">
  <div class="photo">📷</div>
  <div class="photo">📷</div>
  <div class="photo">📷</div>
  <div class="photo">📷</div>
  <div class="photo">📷</div>
  <div class="photo">📷</div>
  <div class="photo">📷</div>
  <div class="photo">📷</div>
</div>
css
.gallery {
  display: grid;

  /* 核心:一行代碼實現響應式! */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  padding: 16px;
}

.photo {
  aspect-ratio: 1;  /* 正方形 */
  background: linear-gradient(135deg, #667eea, #764ba2);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
}

💡 亮點:不管屏幕多寬多窄,相冊都會自動調整每行的照片數量,每張照片至少 200px 寬!

6.3 練習三:儀表盤佈局

html
<div class="dashboard">
  <div class="card stats">統計概覽</div>
  <div class="card chart">圖表區域</div>
  <div class="card table">數據表格</div>
  <div class="card todo">待辦事項</div>
</div>
css
.dashboard {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-rows: auto auto auto;
  gap: 16px;
  padding: 16px;
}

.stats {
  /* 跨兩列 */
  grid-column: 1 / -1;  /* -1 表示到最後一條線 */
  background: #e3f2fd;
}

.chart {
  /* 佔據第一列,第二行 */
  grid-column: 1;
  grid-row: 2;
  height: 300px;
  background: #f3e5f5;
}

.table {
  /* 佔據第一列,第三行 */
  grid-column: 1;
  grid-row: 3;
  height: 200px;
  background: #e8f5e9;
}

.todo {
  /* 佔據第二列,跨第二和第三行 */
  grid-column: 2;
  grid-row: 2 / 4;  /* 從第2行到第4行 */
  background: #fff3e0;
}

.card {
  border-radius: 8px;
  padding: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: bold;
}
┌──────────────────────────────┐
│         統計概覽              │
├────────────────┬─────────────┤
│                │             │
│     圖表區域    │  待辦事項    │
│                │             │
├────────────────┤             │
│                │             │
│     數據表格    │             │
│                │             │
└────────────────┴─────────────┘

6.4 練習四:聖盃佈局

經典的「聖盃佈局」(Holy Grail Layout):

html
<div class="holy-grail">
  <header>頭部</header>
  <nav>導航</nav>
  <main>主內容</main>
  <aside>側邊欄</aside>
  <footer>底部</footer>
</div>
css
.holy-grail {
  display: grid;
  min-height: 100vh;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 80px 1fr 60px;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  gap: 12px;
  padding: 12px;
}

header { grid-area: header; background: #1a1a2e; color: white; }
nav    { grid-area: nav;    background: #16213e; color: white; }
main   { grid-area: main;   background: #f5f5f5; }
aside  { grid-area: aside;  background: #16213e; color: white; }
footer { grid-area: footer; background: #1a1a2e; color: white; }

/* 所有區域通用樣式 */
.holy-grail > * {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: 18px;
  font-weight: bold;
}

/* 響應式 */
@media (max-width: 768px) {
  .holy-grail {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "nav"
      "aside"
      "footer";
  }
}

6.5 練習五:表單佈局

用 Grid 對齊標籤和輸入框:

html
<form class="form">
  <label>用戶名</label>
  <input type="text" placeholder="請輸入用戶名">

  <label>郵箱</label>
  <input type="email" placeholder="請輸入郵箱">

  <label>個人簡介</label>
  <textarea placeholder="請輸入簡介"></textarea>

  <div></div>
  <button type="submit">提交</button>
</form>
css
.form {
  display: grid;
  grid-template-columns: 100px 1fr;  /* 標籤100px,輸入框撐滿 */
  gap: 12px 16px;  /* 行間距12px,列間距16px */
  max-width: 500px;
}

.form label {
  text-align: right;
  line-height: 36px;  /* 和輸入框等高 */
}

.form input,
.form textarea {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 14px;
}

.form textarea {
  height: 80px;
  resize: vertical;
}

.form button {
  grid-column: 2;  /* 按鈕放在第二列 */
  justify-self: start;  /* 靠左對齊 */
  padding: 8px 24px;
  background: #4a90d9;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}

七、高級技巧

7.1 minmax() 函數

設置列寬的範圍:

css
.grid {
  display: grid;

  /* 每列最少200px,最多1fr */
  grid-template-columns: repeat(3, minmax(200px, 1fr));

  /* 側邊欄最少200px,最多300px */
  grid-template-columns: minmax(200px, 300px) 1fr;
}

7.2 auto 關鍵字

讓行或列根據內容自動計算:

css
.grid {
  display: grid;

  /* 中間列根據內容撐開,兩邊均分 */
  grid-template-columns: 1fr auto 1fr;
}

7.3 嵌套 Grid

Grid 可以嵌套使用:

css
.outer {
  display: grid;
  grid-template-columns: 200px 1fr;
}

.sidebar {
  /* 側邊欄內部也用 Grid */
  display: grid;
  grid-template-rows: auto auto auto;
  gap: 8px;
}

.content {
  /* 內容區用 Grid 做卡片列表 */
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

7.4 Grid + Flexbox 混合使用

實際開發中,Grid 和 Flexbox 經常配合使用:

css
/* Grid 負責整體佈局 */
.page {
  display: grid;
  grid-template-areas:
    "header"
    "main"
    "footer";
  grid-template-rows: 60px 1fr 40px;
  min-height: 100vh;
}

/* Flexbox 負責頭部內部排列 */
.header {
  grid-area: header;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}

💡 黃金法則:Grid 做「整體佈局」,Flexbox 做「局部排列」。


八、常見問題

8.1 Grid 和 Flexbox 該選哪個?

需求推薦
一行或一列的排列Flexbox
多行多列的網格Grid
整頁佈局Grid
導航欄、按鈕組Flexbox
卡片居中Flexbox(更簡單)
響應式相冊Grid(auto-fit 更方便)
複雜表單對齊Grid

8.2 為什麼 grid-template-areas 不生效?

css
/* 問題:名字不匹配 */
.grid {
  grid-template-areas:
    "header header"
    "main main";
}

.header {
  grid-area: header;  /* ✅ 匹配 */
}

.main-content {
  grid-area: main;    /* ❌ 不匹配!grid-template-areas 裡寫的是 "main",但要確保完全一致 */
}

解決: 確保名字完全一致,且每個區域必須是矩形。

8.3 為什麼子元素沒有在格子里居中?

css
/* 問題:Grid 默認 stretch(拉伸),但子元素有固定尺寸時不會居中 */
.grid {
  display: grid;
  grid-template-columns: 200px 200px;
}

.item {
  width: 100px;  /* 固定寬度,但不在格子中間 */
}

/* 解決:加對齊屬性 */
.grid {
  display: grid;
  grid-template-columns: 200px 200px;
  justify-items: center;  /* 水平居中 */
  align-items: center;    /* 垂直居中 */
}

九、Grid 速查表

9.1 容器屬性

屬性作用常用值
display開啟網格佈局grid
grid-template-columns定義列repeat(3, 1fr)
grid-template-rows定義行100px 1fr 60px
grid-template-areas命名區域"header header" "sidebar main"
gap間距16px
justify-items水平對齊(所有子元素)center
align-items垂直對齊(所有子元素)center
justify-content網格水平位置center
align-content網格垂直位置center

9.2 子元素屬性

屬性作用常用值
grid-column佔據的列1 / 3span 2
grid-row佔據的行1 / 3span 2
grid-area命名區域header
justify-self單獨水平對齊center
align-self單獨垂直對齊center

9.3 常用單位

單位含義例子
px固定像素200px
fr按比例分配1fr 2fr
auto自動auto
%百分比50%
minmax()範圍minmax(200px, 1fr)
repeat()重複repeat(3, 1fr)

9.4 最常用組合

場景CSS
等寬3列grid-template-columns: repeat(3, 1fr)
響應式網格grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))
整頁佈局grid-template-areas: "header header" "sidebar main" "footer footer"
跨列元素grid-column: 1 / -1

十、總結

回顧本教程的要點:

  1. display: grid 開啟網格佈局
  2. grid-template-columns 定義列,最常用的單位是 fr
  3. repeat() 簡化重複列的定義
  4. auto-fit + minmax() 一行代碼實現響應式網格
  5. grid-template-areas 用畫圖的方式定義佈局,最直觀
  6. gap 設置間距,行列可以分別設置
  7. 網格線 用數字編號,1 / 3 表示從第1條線到第3條線
  8. span N 表示跨越 N 個格子
  9. Grid 做整體佈局,Flexbox 做局部排列 是最佳實踐
  10. -1 表示最後一條網格線,grid-column: 1 / -1 就是跨滿整行

掌握了 Flexbox 和 Grid,你就擁有了 CSS 佈局的全部武器庫!


相關閱讀:

最後更新於: