TailwindCSS Grid 完整指南:grid-cols、col-span、gap 二維版面一次搞懂 | TailwindCSS 完整教學
在 TailwindCSS 裡,Grid 是專為「二維版面」設計的排版引擎——只要對容器寫上
grid,再用grid-cols-*決定幾欄、grid-rows-*決定幾列、col-span-*讓子項跨欄、gap-*拉開間距,就能一組 utility 搭出相簿網格、儀表板、複雜頁面骨架這些過去得寫一大段 CSS 才能完成的版面。這是 TailwindCSS 完整教學 系列的第十篇,我們會把整套 Grid 工具類從容器到子項、從隱式軌道到 v4 全新的 subgrid 一次講透,並以 v4 為預設、標註與 v3 的差異。
前言
Grid(網格佈局,CSS Grid Layout) 是 CSS 專為「二維排列」設計的版面模型——所謂二維,指的是它能同時控制行(rows)與列(columns)兩個方向。這正是它與上一篇 Flexbox 最本質的差別:Flexbox 一次只管一條軸線(要嘛橫的一排、要嘛縱的一列),而 Grid 讓你像畫棋盤格一樣,先切好幾欄幾列,再把元素精準放進格子裡,甚至讓某個元素橫跨數欄、縱跨數列。在 Grid 出現以前,要做出「三欄卡片牆」「後台儀表板」「主內容+左右側欄」這類版面,得靠 float、table、絕對定位這些 hack 拼湊,既難寫又難維護;有了 Grid,幾個 grid-cols 與 col-span 就能優雅搞定。而 TailwindCSS 把整套 Grid 規格一對一包裝成好記、可組合的 utility class,你不必再手寫 grid-template-columns: repeat(3, minmax(0, 1fr)),只要 grid-cols-3 就好。
用一個現實世界的類比來理解:一個 grid 容器,就像一面可以自由劃分格線的「置物櫃牆」。你先決定這面牆要切成幾欄幾列(grid-cols-3、grid-rows-2),牆上就出現一格格整齊的置物空間;接著你把東西(子項)放進去,預設一格放一個,但你也可以讓某個大件物品橫跨兩格(col-span-2)或指定它從第幾條格線開始、到第幾條結束(col-start-2 col-end-4);格子之間要留多寬的縫由 gap-* 決定;當東西比格子多時,牆會自動長出新的一排(隱式軌道,由 auto-rows-* 控制高度);甚至你可以讓每格裡的東西統一置中(place-items-center)。Tailwind 把這面「智慧置物牆」的每個旋鈕都做成一顆好記的 class,讓你像貼標籤一樣組合出想要的二維版面。
本篇你將學到:
- 定義網格骨架:
grid/inline-grid建立容器、grid-cols-*定義欄、grid-rows-*定義列、gap-*控制格線間距 - 子項的跨欄與定位:
col-span-*/row-span-*跨欄跨列、col-start-*/col-end-*依網格線精準定位、col-span-full橫跨整行 - 填充與隱式軌道:
grid-flow-*控制填充方向與 dense 密集排列、auto-cols-*/auto-rows-*控制自動生成軌道的尺寸 - 對齊與進階:
place-items-*/place-content-*/justify-items-*格內對齊、minmax與任意值grid-cols-[...]、以及 v4 全新的subgrid
本系列以 TailwindCSS v4 為預設版本,本篇會明確標註每一項與 v3 的差異。
核心概念
Grid 工具類全景:容器 vs 子項
和 Flexbox 一樣,學 Grid 的第一步是分清楚「哪些 class 寫在容器上、哪些寫在子項上」。定義網格結構的工具(幾欄、幾列、間距、填充方向、對齊)都寫在 grid 容器上;而跨欄跨列、指定起訖網格線的工具則寫在子項上。下面這張表把兩類工具並列,先建立全景地圖:
| 作用對象 | CSS 屬性 | 代表工具類 | 用途 |
|---|---|---|---|
| 容器 | display | grid、inline-grid | 宣告這是 grid 容器 |
| 容器 | grid-template-columns | grid-cols-1~grid-cols-12、grid-cols-none | 定義幾欄、各欄寬度 |
| 容器 | grid-template-rows | grid-rows-1~grid-rows-6、grid-rows-none | 定義幾列、各列高度 |
| 容器 | gap | gap-4、gap-x-4、gap-y-2 | 格線之間的間距 |
| 容器 | grid-auto-flow | grid-flow-row、grid-flow-col、grid-flow-row-dense | 自動填充的方向與密集排列 |
| 容器 | grid-auto-columns | auto-cols-auto、auto-cols-fr、auto-cols-min | 隱式(自動生成)欄的尺寸 |
| 容器 | grid-auto-rows | auto-rows-auto、auto-rows-fr、auto-rows-min | 隱式列的尺寸 |
| 容器 | place-items / justify-items | place-items-center、justify-items-start | 所有子項在格子內的對齊 |
| 容器 | place-content | place-content-center、place-content-between | 整個網格在容器內的對齊分配 |
| 子項 | grid-column | col-span-2、col-span-full | 跨幾欄/橫跨整行 |
| 子項 | grid-column-start/end | col-start-2、col-end-4 | 從第幾條線開始、到第幾條線結束 |
| 子項 | grid-row | row-span-2、row-span-full | 跨幾列/縱跨整欄 |
| 子項 | grid-row-start/end | row-start-1、row-end-3 | 列方向的起訖網格線 |
| 子項 | place-self / justify-self | place-self-center、justify-self-end | 覆蓋單一子項在格子內的對齊 |
這張表最需要先建立的認知只有一句話:grid-cols-*、grid-rows-*、gap-*、grid-flow-*、auto-*、place-items-* 這些是「容器的旋鈕」,寫在 grid 容器上;col-span-*、row-span-*、col-start-*、place-self-* 這些是「子項的旋鈕」,寫在容器的直接子元素上。 記住這個分界,你就避開了 Grid 一半的錯誤。
網格線思維:Grid 的心臟
要真正搞懂 col-span 與 col-start/col-end,必須先建立「網格線(grid line)」的概念。當你寫 grid-cols-3 時,Tailwind 幫你切出三欄,但真正決定位置的是四條垂直的網格線——欄是格子,線是格子的邊界。線從左到右編號為 1、2、3、4,而 col-start/col-end 指的正是這些線的編號:
grid-cols-3(3 欄 → 4 條垂直網格線)
線1 線2 線3 線4
│ col 1 │ col 2 │ col 3 │
▼ ▼ ▼ ▼
┌──────────┬──────────┬──────────┐
│ item 1 │ item 2 │ item 3 │ row 1
├──────────┼──────────┼──────────┤
│ item 4 │ item 5 │ item 6 │ row 2
└──────────┴──────────┴──────────┘
col-span-2(跨 2 欄,等同從某條線橫跨 2 格)
┌──────────────────────┬──────────┐
│ col-span-2 的區塊 │ item │
├──────────┬───────────┴──────────┤
│ item │ col-span-2 的區塊 │
└──────────┴──────────────────────┘
col-start-2 col-end-4(從線 2 明確定位到線 4)
線1 線2 線3 線4
┌──────────┬──────────────────────┐
│ 留空 │ 這個元素放在這裡 │
└──────────┴──────────────────────┘
有了網格線的圖像,三組定位工具的分工就清楚了。col-span-*(對應 grid-column: span N)表達的是「跨幾個格子」,它不在乎從哪條線開始,只表達寬度——col-span-2 就是佔兩欄、col-span-full(對應 grid-column: 1 / -1)則是從第一條線橫跨到最後一條、獨佔整行。而 col-start-* 與 col-end-*(對應 grid-column-start/grid-column-end)表達的是「明確從第幾條線到第幾條線」——col-start-2 col-end-4 就是精準地把元素放在線 2 到線 4 之間。列方向完全對稱:row-span-* 跨幾列、row-start-*/row-end-* 依水平網格線定位。當版面規則、每個元素等寬時用 col-span;當你需要把某個元素精準釘在某個位置(例如跳過第一欄、從第二欄開始)時用 col-start/col-end。
隱式軌道與 grid-flow:格子不夠時會怎樣
一個常被忽略但很關鍵的概念是顯式網格(explicit grid)與隱式網格(implicit grid)的差別。你用 grid-cols-3 grid-rows-2 明確定義的 6 個格子是「顯式網格」;但如果你放了 8 個子項,多出來的 2 個怎麼辦?Grid 會自動生成新的一列來容納它們——這些自動長出來的軌道就是「隱式網格」。隱式列的高度預設是 auto(由內容決定),如果你想讓它們有固定或統一的尺寸,就要用 auto-rows-*:auto-rows-fr(每列等分剩餘空間)、auto-rows-min(貼合內容最小高度)、auto-rows-[8rem](任意固定高度)。對應地,auto-cols-* 控制隱式欄的寬度。
而填充方向由 grid-flow-* 決定。預設是 grid-flow-row——子項按「列優先」逐格填入,填滿一列才換下一列。改成 grid-flow-col 則變成「欄優先」,先填滿一欄才換下一欄。此外還有 dense(密集排列)變體:當網格裡因為某些元素跨欄跨列而產生空洞時,grid-flow-row-dense 會讓後面較小的元素回頭填補這些空洞,讓版面更緊密:
grid-flow-col(欄優先填充) grid-flow-row-dense(回填空洞)
┌───┬───┬───┐ ┌───────┬───┐
│ 1 │ 3 │ 5 │ ← 先往下填滿 │ 大 │ 2 │ ← 3 回頭填補
│ │ │ │ 一欄再換欄 │ 區塊 ├───┤ 左側空洞
├───┼───┼───┤ │ │ 3 │
│ 2 │ 4 │ 6 │ └───────┴───┘
└───┴───┴───┘
v4 差異標註:
grid-flow的 dense 變體在 v4 拆分成grid-flow-row-dense與grid-flow-col-dense兩個明確的 class,語義比 v3 更清晰。此外,v4 正式支援grid-cols-subgrid/grid-rows-subgrid(稍後在範例中詳談),這是 v3 沒有內建的重量級新特性。
place 系列:格內對齊的簡寫
Grid 的對齊工具比 Flexbox 多一組,容易混淆,這裡一次釐清。在 Grid 中,對齊分「單一子項在它自己的格子內如何擺放」與「整個網格在容器內如何分配」兩個層級:
justify-items-*(水平/inline 軸)+items-*(垂直/block 軸):控制所有子項在各自格子內的對齊。place-items-*則是這兩者的簡寫——place-items-center一個 class 就讓所有子項在格子裡水平垂直都置中,這是 Grid 置中最簡潔的寫法。place-content-*:當網格的總尺寸小於容器時,控制整個網格在容器內如何分配(例如place-content-center把整組格子擺到容器正中央、place-content-between上下撐開)。place-self-*/justify-self-*:覆蓋單一子項的對齊,讓少數例外元素跳脫容器統一的place-items-*設定。
記憶口訣:items 管垂直、justify-items 管水平、place-items 是兩者的簡寫;帶 content 的是「整個網格的分配」,帶 self 的是「單一子項的例外」。 v4 把 place 系列補得更完整,新增了 place-content-baseline 等值,整體命名與 v3 相容,遷移幾乎不需改動。
實作範例
理論看完,我們用幾個可執行的範例把工具串起來。以下都是完整的 HTML + Tailwind,可直接貼進頁面觀察效果。
範例一:響應式卡片網格
Grid 最經典的用途就是卡片網格——手機單欄、平板雙欄、桌面三欄,換行、間距全部自動處理:
<!-- 響應式卡片網格:手機 1 欄、平板 2 欄、桌面 3 欄 -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 p-6">
<div class="bg-white rounded-xl border border-gray-200 p-6 hover:shadow-md transition-shadow">
<img src="/img-1.jpg" alt="封面" class="w-full h-48 object-cover rounded-lg mb-4">
<h3 class="text-lg font-semibold text-gray-900">卡片標題</h3>
<p class="text-gray-600 text-sm mt-2 leading-relaxed">卡片描述文字,數量再多也會自動換行到下一列。</p>
<div class="mt-4 flex items-center justify-between">
<span class="text-xs font-medium text-cyan-700 bg-cyan-50 px-2 py-1 rounded">標籤</span>
<a href="#" class="text-sm font-medium text-gray-900 hover:text-cyan-600">閱讀更多 →</a>
</div>
</div>
<!-- 重複相同結構的更多卡片,超過欄數會自動換到下一列 -->
</div>
這個範例的核心就一行:grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6。grid 宣告容器、grid-cols-1 是手機的預設單欄,再用響應式前綴 sm:grid-cols-2、lg:grid-cols-3 在斷點切換欄數。gap-6 一次搞定水平與垂直間距——注意這裡完全不需要處理「最後一張卡片多餘的右邊距」或「換行後上下間距不一致」的問題,這正是 Grid(與 Flexbox 的 gap)勝過 margin 的地方。卡片數量無論幾張,超過欄數就自動換到隱式生成的下一列,你什麼都不用多寫。這也是為什麼卡片牆這種場景 Grid 通常比 Flexbox 更省心——它天生就是為「規則的行列」設計的。留意卡片內部的 flex items-center justify-between 用的是上一篇的 Flexbox,這正是「外層 Grid 切版、內層 Flexbox 排列」的經典搭配。
範例二:儀表板版面(col-span 跨欄)
第二個高頻場景是後台儀表板——大圖表跨多欄、旁邊放小統計卡、下方再排一列等寬指標。這是 grid-cols-12 搭配 col-span-* 的經典舞台:
<!-- 12 欄儀表板:用 col-span 精確分配區塊寬度 -->
<div class="grid grid-cols-12 gap-4 p-4">
<!-- 主圖表:桌面跨 8 欄,手機獨佔整行 -->
<div class="col-span-12 lg:col-span-8 bg-white rounded-xl p-6 border border-gray-200">
<h2 class="text-lg font-semibold mb-4">銷售趨勢</h2>
<!-- 圖表區 -->
</div>
<!-- 側邊統計:桌面跨 4 欄,內部再用 grid-rows-2 疊兩張小卡 -->
<div class="col-span-12 lg:col-span-4 grid grid-rows-2 gap-4">
<div class="bg-cyan-600 text-white rounded-xl p-6">
<p class="text-sm font-medium opacity-80">月銷售額</p>
<p class="text-3xl font-bold mt-1">NT$1.28M</p>
</div>
<div class="bg-emerald-600 text-white rounded-xl p-6">
<p class="text-sm font-medium opacity-80">新客戶</p>
<p class="text-3xl font-bold mt-1">2,847</p>
</div>
</div>
<!-- 下方三欄等寬指標卡:各跨 4 欄(4+4+4 = 12) -->
<div class="col-span-12 md:col-span-4 bg-white rounded-xl p-6 border border-gray-200">
<p class="text-sm text-gray-500">訂單數</p>
<p class="text-2xl font-bold text-gray-900 mt-1">1,429</p>
</div>
<div class="col-span-12 md:col-span-4 bg-white rounded-xl p-6 border border-gray-200">
<p class="text-sm text-gray-500">轉換率</p>
<p class="text-2xl font-bold text-gray-900 mt-1">3.24%</p>
</div>
<div class="col-span-12 md:col-span-4 bg-white rounded-xl p-6 border border-gray-200">
<p class="text-sm text-gray-500">退貨率</p>
<p class="text-2xl font-bold text-gray-900 mt-1">0.8%</p>
</div>
</div>
這個範例展示了 12 欄系統的威力——把容器切成 12 個等寬單位,再用 col-span-* 靈活分配:主圖表 lg:col-span-8(佔三分之二)、側邊統計 lg:col-span-4(佔三分之一),加起來剛好 12 欄填滿一列;下方三張指標卡各 md:col-span-4(4+4+4)再填滿下一列。12 欄之所以成為業界慣例,是因為 12 能被 2、3、4、6 整除,要切二等分、三等分、四等分都剛好。留意每個區塊都先寫 col-span-12(手機獨佔整行),再用斷點前綴覆蓋成桌面的多欄配置——這是響應式 Grid 的標準寫法。另外注意側邊統計區塊本身又是一個 grid grid-rows-2 的巢狀 Grid,把兩張小卡上下均分,這種「格子裡再切格子」的巢狀網格是複雜版面的常見手法。
範例三:任意值與 minmax(精確軌道 + 自動填充)
當你需要「側欄固定寬、主內容彈性」或「讓瀏覽器自己決定一行放幾張卡」這種內建 grid-cols-N 做不到的版面時,就輪到**任意值(arbitrary values)**與 minmax 上場:
<!-- 任意欄結構:左側欄 240px + 彈性主內容 + 右側欄 240px -->
<div class="grid grid-cols-[240px_1fr_240px] gap-4 min-h-screen">
<aside class="bg-gray-50 p-4 border-r border-gray-200">左側邊欄(固定 240px)</aside>
<main class="p-6">主內容(1fr 吃掉剩餘空間)</main>
<aside class="bg-gray-50 p-4 border-l border-gray-200">右側邊欄(固定 240px)</aside>
</div>
<!-- auto-fill + minmax:讓瀏覽器自動決定一行放幾張卡(RWD 免斷點) -->
<div class="grid grid-cols-[repeat(auto-fill,minmax(250px,1fr))] gap-6">
<div class="bg-white rounded-xl border p-6">卡片</div>
<div class="bg-white rounded-xl border p-6">卡片</div>
<div class="bg-white rounded-xl border p-6">卡片</div>
<!-- 每張卡最小 250px、最大 1fr,瀏覽器自動塞滿每一行 -->
</div>
<!-- 用 minmax 防止列高被短內容壓垮、又不讓長內容溢出 -->
<div class="grid grid-rows-[minmax(120px,auto)_1fr] gap-4">
<header class="bg-gray-100 p-4">頁頭(至少 120px 高,內容多就自動長高)</header>
<main class="p-4">主內容</main>
</div>
這裡有三個關鍵技巧。第一,grid-cols-[240px_1fr_240px] 用任意值直接寫出 grid-template-columns 的內容——方括號裡用底線 _ 代替空格,1fr 是 fraction 單位(吃掉剩餘空間的比例),這一行就搭出經典的「固定側欄 + 彈性主欄」三欄版面。第二,grid-cols-[repeat(auto-fill,minmax(250px,1fr))] 是自動響應式的神招:minmax(250px,1fr) 表示每欄最小 250px、最大 1fr,auto-fill 讓瀏覽器自己算一行能塞幾欄——視窗變寬就多塞幾張、變窄就自動換行,完全不需要寫任何 sm:/lg: 斷點。第三,grid-rows-[minmax(120px,auto)] 展示 minmax 在列高上的用途:minmax(下限, 上限) 保證軌道至少有 120px、但內容變多時能自動長高,避免了「固定高度撐爆內容」與「內容太少塌陷」兩種尷尬。這也是官方推薦的做法——用 minmax 取代寫死的固定 grid-rows-[100px_100px],讓軌道有彈性。
範例四:Subgrid 對齊卡片按鈕(v4 新特性)
最後一個範例示範 v4 的招牌新特性 subgrid,它解決了卡片列表「每張卡標題長短不一、按鈕高低參差」的經典難題:
<!-- Subgrid:讓每張卡的標題/內容/按鈕分別對齊到父層網格線 -->
<div class="grid grid-cols-3 gap-6">
<!-- 每張卡都繼承父層的列軌道:標題、內容、按鈕三列完美對齊 -->
<article class="grid grid-rows-subgrid row-span-3 bg-white rounded-xl p-6 border border-gray-200">
<h3 class="text-lg font-semibold">短標題</h3>
<p class="text-gray-600 text-sm">描述文字。</p>
<a href="#" class="text-sm font-medium text-cyan-600">閱讀更多 →</a>
</article>
<article class="grid grid-rows-subgrid row-span-3 bg-white rounded-xl p-6 border border-gray-200">
<h3 class="text-lg font-semibold">這是一個比較長、會佔到兩行的卡片標題</h3>
<p class="text-gray-600 text-sm">描述文字。</p>
<a href="#" class="text-sm font-medium text-cyan-600">閱讀更多 →</a>
</article>
<article class="grid grid-rows-subgrid row-span-3 bg-white rounded-xl p-6 border border-gray-200">
<h3 class="text-lg font-semibold">中等長度的標題</h3>
<p class="text-gray-600 text-sm">描述文字。</p>
<a href="#" class="text-sm font-medium text-cyan-600">閱讀更多 →</a>
</article>
</div>
這個範例的魔法在於 grid-rows-subgrid row-span-3。父容器是 grid grid-cols-3,每張卡片本身也是一個 Grid,但它不自己開新的列軌道,而是用 grid-rows-subgrid 繼承父層的列結構,並用 row-span-3 佔滿標題、內容、按鈕三列。結果是:無論哪張卡的標題是一行還是兩行,所有卡片的標題列、內容列、按鈕列都會對齊到同一條網格線——第二張卡的長標題撐高了那一列,其他兩張卡的標題列也會跟著等高,於是三張卡的按鈕最終落在完全相同的水平位置。
沒有 subgrid(各卡獨立排版) 使用 subgrid(列對齊父層網格線)
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 短標題 │ │ 長標題 │ │ 短標題 │ │ 長標題 │
│ │ │ 佔兩行 │ │ │ │ 佔兩行 │
│ 描述... │ │ 描述... │ │──────────│ │──────────│ ← 同一線
│ [按鈕] │ │ │ │ 描述... │ │ 描述... │
└──────────┘ │ [按鈕] │ │──────────│ │──────────│ ← 同一線
└──────────┘ │ [按鈕] │ │ [按鈕] │ ← 完美對齊
↑ 按鈕高低不一 └──────────┘ └──────────┘
在 v3 時代,要達成這種對齊得寫原生 CSS、或用固定高度硬撐、甚至靠 JavaScript 量測——v4 的 grid-rows-subgrid 一個 utility 就搞定。唯一要留意的是 subgrid 屬於較新的 CSS 特性,正式用於生產環境前,建議先確認目標使用者的瀏覽器版本支援度。
常見錯誤與最佳實踐
四個最容易踩的 Grid 坑
坑一:搞不清該用 Grid 還是 Flexbox。 這是最根本的選型錯誤。判斷標準只有一句話:需要同時控制行與列(二維)用 Grid,只需要一排或一列(一維)用 Flexbox。 卡片牆、儀表板、頁面骨架這種有明確行列規則的用 Grid;導覽列、按鈕組、標籤雲這種一維、項目數動態的用 Flexbox。硬用 Flexbox 的 flex-wrap 去模擬網格,會遇到「換行後每項寬度難以整齊對齊」的麻煩,而 Grid 天生就整齊。
坑二:以為 col-span-full 是固定跨 12 欄。 col-span-full(grid-column: 1 / -1)是跨越目前 Grid context 的所有欄,是相對的。父層是 grid-cols-4 就跨 4 欄、grid-cols-12 就跨 12 欄。在巢狀 Grid 中尤其要注意它只對「自己所在那一層」生效:
<div class="grid grid-cols-4 gap-4">
<div class="col-span-full bg-gray-100 p-4">標題列(自動跨滿 4 欄)</div> <!-- ✅ 跟著欄數走 -->
<div class="p-4">A</div>
<div class="p-4">B</div>
</div>
坑三:隱式列溢出或高度不受控。 當子項數量超過顯式定義的格子時,Grid 會自動生成隱式列,其高度預設 auto(由內容決定),可能導致每列高度參差。若要統一隱式列的高度,用 auto-rows-*;另外,別用寫死的固定高度 grid-rows-[100px_100px] 限制內容,內容一多就溢出,改用 minmax:
<div class="grid grid-cols-3 auto-rows-[8rem] gap-4">...</div> <!-- ✅ 隱式列統一 8rem 高 -->
<div class="grid grid-rows-[100px_100px]">內容超過會溢出</div> <!-- ❌ 固定高度限死內容 -->
<div class="grid grid-rows-[minmax(100px,auto)_1fr]">彈性又有下限</div> <!-- ✅ 至少 100px、能長高 -->
坑四:對 Grid 子項用 float,或混淆 Grid 與 Flex 的對齊工具。 Grid 容器內的子項套 float 完全無效(Grid 會忽略它);另外別把 Flexbox 的 justify-content(justify-*)觀念直接搬來——在 Grid 裡,控制子項在格子內對齊要用 place-items-*/justify-items-*,控制整個網格分配才用 justify-*/place-content-*,兩者管的層級不同。想單純置中所有格子內容,最省事的是容器加 place-items-center。
Grid 最佳實踐清單
- 先分清容器與子項工具:
grid-cols-*/grid-rows-*/gap-*/grid-flow-*/place-items-*寫容器,col-span-*/row-span-*/col-start-*/place-self-*寫子項——這是避開一半錯誤的關鍵。 - 二維用 Grid、一維用 Flexbox:需要行列同時控制才用 Grid,只需一排一列交給 Flexbox;兩者常搭配(外層 Grid 切版、內層 Flex 排列)。
- 卡片網格用
grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-*:響應式欄數 + gap,一行搞定過去要寫一大段的版面。 - 複雜版面用
grid-cols-12+col-span-*:12 欄系統靈活可整除,是儀表板與頁面骨架的標準做法。 - 軌道尺寸用
minmax,不要寫死固定值:minmax(下限,auto)保證彈性;免斷點 RWD 用grid-cols-[repeat(auto-fill,minmax(250px,1fr))]。 - 卡片列表要對齊底部按鈕就用 subgrid:v4 的
grid-rows-subgrid row-span-N是解決按鈕高低不一的最佳解。 - 間距一律用
gap-*,不用 margin:頭尾乾淨、換行也對齊,語義更清楚。
小結
這是 TailwindCSS 完整教學 系列的第十篇。上一篇 《Flexbox》 我們把一維版面引擎講透——用 flex 宣告彈性容器、justify-* 管主軸分配、items-* 管交軸對齊、flex-1 讓子項等分空間,解決置中、等分、換行這些一維排列需求。這一篇則進入二維版面的世界,把 Grid 從容器骨架到子項定位、從隱式軌道到 v4 全新的 subgrid 一次講清楚。回顧幾個重點:
- 容器 vs 子項是第一分界:
grid-cols-*/grid-rows-*/gap-*/grid-flow-*/auto-*/place-items-*寫在容器上,col-span-*/row-span-*/col-start-*/col-end-*/place-self-*寫在子項上。 - 網格線思維是心臟:
col-span-*表達「跨幾格」、col-start-*/col-end-*表達「明確從第幾條線到第幾條線」,col-span-full則橫跨整行且跟著欄數走。 - 隱式軌道與填充:格子不夠時 Grid 自動生成隱式列,用
auto-rows-*控制其尺寸、grid-flow-*(含 v4 拆分的 dense 變體)控制填充方向。 - 對齊與進階:
place-items-*是格內對齊最省事的簡寫、place-content-*分配整個網格、minmax與任意值grid-cols-[...]打造彈性軌道,而 v4 的subgrid解決了卡片對齊的經典難題。 - 最容易踩的坑:Grid 與 Flexbox 選型、
col-span-full是相對的、隱式列用minmax別寫死、Grid 子項的float無效。
掌握了 Flexbox 與 Grid 這兩大版面引擎,你已經能搭出絕大多數的頁面骨架。但有些場景需要讓元素「脫離正常流」——像是固定在角落的浮動按鈕、跟隨滾動的黏性導覽列、疊在圖片上的標籤、置中的彈窗遮罩。下一篇 《定位系統》,我們會進入 position 的世界,把 relative、absolute、fixed、sticky 這些 utility,以及 top/right/bottom/left、z-index 一次講透,看 Tailwind 如何用一組 utility 精準控制元素在畫面上的絕對位置與層疊順序。