WorkBlog

CSS Grid 切版教學:從入門到實戰

楊靜宜
CSS Grid 切版教學:從入門到實戰

每次看到那些排版精美的網站,你有沒有好奇過它們的版面是怎麼切出來的?在 CSS Grid 出現之前,我們用 float、inline-block、甚至各種 hack 手段來排版,那段日子真的不堪回首。現在有了 CSS Grid,不管是簡單的兩欄式佈局,還是複雜的雜誌風格版面,都能輕鬆搞定。今天就讓我帶你從最基礎的概念開始,一路走到能實際應用的程度。

CSS Grid 是什麼

CSS Grid Layout 是一套二維的排版系統。注意這個「二維」——這是它跟 Flexbox 最根本的區別。Flexbox 本質上是一維的,它一次只能處理一個方向(水平或垂直)的排列。但 CSS Grid 可以同時控制行和列,讓你在二維平面上精確地安排每個元素的位置。

打個比方,如果 Flexbox 是一條繩子,你可以把東西一個接一個地掛在上面;那 CSS Grid 就是一張棋盤,你可以把每個棋子放在任何你想放的格子裡。兩者各有所長,不是互相取代的關係。實務上,我通常在大框架的佈局用 Grid,在元件內部的排列用 Flexbox,這樣搭配起來特別順手。

2026 年的瀏覽器對 CSS Grid 的支援已經非常完善了,包括比較新的 Subgrid 功能,所有主流瀏覽器都已經支援。你可以放心地在生產環境中使用,不需要擔心相容性問題。

基本術語與概念

在開始寫程式碼之前,先搞清楚幾個基本術語。這些術語聽起來可能有點枯燥,但理解了之後,後面的內容就會輕鬆很多。

Grid Container(網格容器):設定了 display: grid 的元素,就是一個 Grid Container。它的直接子元素會自動變成 Grid Items。

Grid Item(網格項目):Grid Container 的直接子元素。注意是「直接」子元素,孫元素不算。

Grid Line(網格線):構成網格結構的分隔線,包括水平線和垂直線。線的編號從 1 開始,而不是從 0 開始。

Grid Track(網格軌道):兩條相鄰網格線之間的空間,簡單來說就是一行或一列。

Grid Cell(網格格子):兩條相鄰水平線和兩條相鄰垂直線圍成的空間,就是最小的網格單位。

Grid Area(網格區域):一個或多個 Grid Cell 組成的矩形區域。

grid-template-columns 與 rows

最常用的兩個屬性就是 grid-template-columnsgrid-template-rows。它們分別定義了網格的欄和列。

.container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 80px 1fr 60px;
}

這段程式碼建立了一個三欄三列的網格。兩邊的欄各寬 200px,中間的欄佔據剩餘空間(1fr)。行的部分也類似,上面 80px 給 header,中間自適應給內容區域,下面 60px 給 footer。

你也可以用 repeat() 函式來簡化重複的定義。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 三等分 */
  grid-template-columns: repeat(4, 200px); /* 四個 200px 的欄 */
  grid-template-columns: repeat(2, 1fr 2fr); /* 交替寬度:1fr 2fr 1fr 2fr */
}

repeat() 的好處是當你需要很多欄的時候不用寫一長串。我曾經看過有人手寫了 12 個 1fr,改成 repeat(12, 1fr) 清爽多了。

fr 單位與彈性佈局

fr 是 CSS Grid 引入的一個特別好用的單位,全名是 fraction(份額)。它代表的是可用空間的一個比例。

.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
}

在這個例子中,容器的空間會被分成 4 份(1+2+1),左欄和右欄各佔 1 份,中間欄佔 2 份。如果容器寬度是 800px,那左右各 200px,中間 400px。

fr 跟百分比的區別在於,fr 是在扣除固定大小的軌道之後才分配的。舉個例子:

.container {
  display: grid;
  grid-template-columns: 300px 1fr 2fr;
  width: 900px;
}

這種情況下,先扣掉 300px 的固定欄,剩下 600px 再按 1:2 的比例分配,所以第二欄 200px、第三欄 400px。如果用百分比的話,就得自己算,而且容器寬度一變就要重新算,非常麻煩。

另外,fr 搭配 minmax() 函式可以設定軌道的最小和最大寬度,這在響應式設計中特別有用。

.container {
  grid-template-columns: repeat(3, minmax(250px, 1fr));
}

每個欄的最小寬度是 250px,最大寬度是 1fr。這樣在大螢幕上三欄等寬,在小螢幕上每欄至少保持 250px 的寬度。如果你想搭配Tailwind CSS 響應式設計教學來學習,可以了解如何在 utility-first 框架中運用 Grid 的概念。

gap 間距設定

gap 屬性用來設定網格項目之間的間距,它是 row-gapcolumn-gap 的簡寫。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px; /* 行列間距都是 20px */
  gap: 20px 30px; /* 行間距 20px,列間距 30px */
  row-gap: 20px; /* 只設定行間距 */
  column-gap: 30px; /* 只設定列間距 */
}

以前要在 Grid 項目之間加間距,得用 margin,然後處理邊緣項目的 margin 問題(第一個和最後一個不要有外側的 margin),超級煩人。gap 直接解決了這個問題——它只在項目「之間」加間距,邊緣不會有多餘的空白。太舒服了。

grid-area 區域命名

這是我個人覺得 CSS Grid 最優雅的功能之一。你可以用可讀的名稱來定義網格區域,然後把元素放到對應的區域裡。

.container {
  display: grid;
  grid-template-columns: 250px 1fr 300px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  gap: 16px;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }

看到了嗎?grid-template-areas 就像是在畫一幅 ASCII 藝術畫,直接用文字描述版面結構。哪個區域佔哪些格子,一目瞭然。而且要修改版面的時候,只要改這幾行字串就好,不用去動 HTML 的結構。

如果某些格子不需要放東西,可以用點(.)來表示空白區域:

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

auto-fill 與 auto-fit 差異

這兩個關鍵字經常讓人搞混,但它們的差異其實很簡單。兩者都用在 repeat() 函式中,讓瀏覽器自動決定要放多少欄。

/* auto-fill:用空軌道填滿剩餘空間 */
.container {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* auto-fit:把剩餘空間分配給現有項目 */
.container {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

差異在於:當容器的空間足夠放更多欄,但實際的項目不夠多的時候,auto-fill 會建立空的軌道來佔位,而 auto-fit 會把多餘的空間分配給已有的項目,讓它們變得更寬。

在大多數情況下,你想用的是 auto-fit,因為它會讓項目自動填滿整個容器寬度,視覺效果比較好。auto-fill 則適合你希望項目保持固定寬度、不要被拉伸的情境。

Subgrid 完整支援

Subgrid 是 CSS Grid Level 2 的重頭戲,到了 2026 年終於在所有主流瀏覽器都獲得了完整支援。它解決了一個長期以來的痛點:巢狀 Grid 的對齊問題。

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3; /* 佔三行 */
}

在沒有 Subgrid 之前,你如果想讓一排卡片的標題、內容、按鈕分別對齊,幾乎是不可能的任務。每張卡片的標題長度不同,內容高度不同,按鈕就會亂跑。有了 Subgrid,子元素可以直接使用父元素的網格軌道,完美對齊。

Subgrid 對於設計系統來說尤其重要。當你需要確保整個頁面的元素都能精確對齊到同一套網格系統時,Subgrid 就是你的最佳夥伴。如果你有使用暗色模式的需求,搭配Tailwind CSS 暗色模式教學一起學習,可以打造出更專業的 UI。

實戰切版範例

學了這麼多理論,來做一個實際的範例吧。我們來切一個典型的部落格首頁版面:上方有一個全寬的 hero 區域,中間是主要內容區加側邊欄,下面是三欄的特色文章區塊。

.blog-layout {
  display: grid;
  grid-template-columns: 1fr min(720px, 100%) 300px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    ". hero hero ."
    ". main sidebar ."
    ". featured featured .";
  gap: 24px 32px;
  padding: 0 16px;
}

.hero { grid-area: hero; }
.main { grid-area: main; }
.sidebar { grid-area: sidebar; }

.featured {
  grid-area: featured;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

@media (max-width: 768px) {
  .blog-layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "hero"
      "main"
      "sidebar"
      "featured";
  }
}

這個範例展示了幾個實用的技巧。首先,用兩邊的 1fr 來建立自動的邊距,讓內容區域維持在頁面中央。min(720px, 100%) 確保主內容區最寬 720px,但在小螢幕上不會超出視窗。

特色文章區塊用了 auto-fit 搭配 minmax(),在不同螢幕寬度下自動調整欄數。大螢幕三欄、中螢幕兩欄、小螢幕一欄,完全不需要額外的 media query。

響應式的部分只用了一個簡單的 media query,把所有區域改成單欄排列。Grid 的好處就是你只要改 grid-template-areas,HTML 完全不用動。如果你正在用 React 開發前端,可以參考React 19 新功能教學來搭配 CSS Grid 打造更好的元件架構。

常見錯誤與最佳實踐

分享幾個我在實務中常看到的錯誤和對應的最佳實踐。

第一,不要過度使用固定寬度。很多人剛開始用 Grid 的時候習慣寫 grid-template-columns: 200px 400px 200px,全部都用固定像素值。這樣做出來的版面在大螢幕上會有很多空白,在小螢幕上可能會超出視窗。盡量用 frminmax() 來保持彈性。

第二,Grid 和 Flexbox 不是非此即彼的選擇。Grid 適合整體頁面佈局和二維排列,Flexbox 適合一維的內容流動。兩者搭配使用才是最佳實踐。比如整個頁面用 Grid 切大區塊,導覽列裡面的選項用 Flexbox 來排列。

第三,注意隱式網格的行為。當 Grid 項目超出你定義的範圍時,Grid 會自動建立額外的軌道(隱式軌道)。你可以用 grid-auto-rowsgrid-auto-columns 來控制這些隱式軌道的大小。

第四,善用瀏覽器的開發者工具。Chrome 和 Firefox 都提供了非常好用的 Grid 視覺化工具,可以讓你看到網格線、區域名稱、軌道大小等資訊。遇到排版問題的時候,先打開 Grid Inspector 看看,通常很快就能找到問題所在。

CSS Grid 是現代前端開發者必須掌握的技能。它不只讓你的程式碼更簡潔,也讓你有能力實現以前不可能(或非常困難)的版面設計。現在就開始在你的下一個專案中使用它吧,相信你很快就會愛上它的。

楊靜宜

前端工程師,CSS 重度愛好者。Tailwind CSS 佈道者。

CSSTailwind前端效能無障礙設計

繼續閱讀

CSS Container Queries 教學:響應式設計的新時代終於來了

CSS Container Queries 教學:響應式設計的新時代終於來了

Media Queries 看的是視窗大小,但元件不一定只活在全寬的地方。Container Queries 讓你的 CSS 根據容器大小來變化,真正實現元件級的響應式設計。

相關文章

你可能也喜歡

探索其他領域的精選好文