CSS 排版像煮咖啡:杯子(HTML)先放好,比例(CSS)調對,整杯才不會溢出。這篇會用一個儀表板範例,帶你從 HTML 結構、grid-template-areas 到響應式版面,逐步做出桌面與手機都能閱讀的 CSS Grid 版面;不用把每個區塊都 position: absolute,否則最後可能連咖啡都要用座標找。
讀完後,你會知道如何把頁面切成具名區域、在主要內容裡建立巢狀網格、用 fr 分配剩餘空間,還能用媒體查詢切換成單欄版面。先把棋盤畫出來,接下來每個區塊就有自己的座位。
建立 HTML 結構
先準備兩個檔案:index.html 放內容,styles.css 放樣式。HTML 不需要知道每個區塊最後要站在哪一格,只要用有意義的 class 告訴 CSS「我是誰」即可。
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Grid 儀表板</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="grid-container">
<header class="header">網站標題</header>
<nav class="top-nav">頂部導覽</nav>
<aside class="sidebar">側邊欄</aside>
<main class="main-content">
<div class="widget widget-1">統計卡片 1</div>
<div class="widget widget-2">統計卡片 2</div>
<div class="widget widget-3">統計卡片 3</div>
<div class="widget widget-4">統計卡片 4</div>
</main>
<section class="extra-content">額外資訊</section>
<section class="notifications">通知</section>
<footer class="footer">頁尾</footer>
</div>
</body>
</html>這裡的 header、nav、aside、main、section 和 footer 也讓文件結構更容易理解。接著,讓最外層的 .grid-container 變成網格容器。

定義主要網格
display: grid 會把元素變成 Grid 容器;直接子元素則會成為 Grid 項目。grid-template-columns 定義欄,grid-template-rows 定義列,而 fr 代表可分配的剩餘空間。
這個範例用三欄:左右欄各佔 0.5fr,中央主要內容佔 2fr。因此中央欄會比左右欄寬,但實際寬度仍會隨容器變化。
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
}
.grid-container {
display: grid;
grid-template-columns: 0.5fr 2fr 0.5fr;
grid-template-rows: auto auto minmax(300px, 1fr) auto auto;
grid-template-areas:
"header header header"
"top-nav top-nav top-nav"
"sidebar main-content extra-content"
"sidebar notifications extra-content"
"footer footer footer";
gap: 10px;
min-height: 100vh;
padding: 10px;
}這裡使用 min-height: 100vh,讓內容少時至少填滿視窗,但不會像固定 height 那樣在內容變多時硬把內容塞出容器。版面不是行李箱,不需要為了合蓋而壓扁內容。
grid-template-areas 是這個範例的重點。每一行代表一列,每個名稱代表一個網格儲存格;相同名稱連在一起,就會形成同一個區域。名稱的數量要對齊,否則整個宣告會變成無效 CSS。
放置標頭與導覽列
接著用 grid-area 把 HTML 元素接到剛才命名的區域。grid-area: header 的意思不是「請瀏覽器自由發揮」,而是「把我放到名為 header 的區域」。
.header {
grid-area: header;
padding: 16px;
color: #fff;
background-color: #388e3c;
text-align: center;
}
.top-nav {
grid-area: top-nav;
padding: 12px;
color: #fff;
background-color: #1976d2;
text-align: center;
}樣式本身可以依專案設計調整;Grid 關心的是位置,不會限制你的顏色、字型或圓角。換句話說,它是排版工具,不是來管你喝美式還是拿鐵的。
設定左右側欄
側欄與額外資訊分別佔據左右兩側。指定 grid-area 後,這些元素就會按照模板排列,不需要為每個元素手動計算欄線編號。
.sidebar {
grid-area: sidebar;
padding: 16px;
background-color: #ffc107;
}
.extra-content {
grid-area: extra-content;
padding: 16px;
background-color: #009688;
}這種寫法的優點是「版面長相」直接寫在容器裡。日後要調整配置時,通常只需修改 grid-template-areas,不用在好幾個選擇器裡追蹤 grid-column 和 grid-row。
在主要內容中建立巢狀網格
Grid 容器可以放在另一個 Grid 項目裡。.main-content 先透過 grid-area 到外層的主要區域,再自己設定 display: grid,成為內層的網格容器。
.main-content {
display: grid;
grid-area: main-content;
grid-template-columns: 1fr 2fr;
grid-template-rows: repeat(2, minmax(120px, auto));
gap: 10px;
padding: 10px;
background-color: #f5f5f5;
}
.widget {
display: grid;
place-items: center;
min-height: 120px;
padding: 16px;
color: #fff;
text-align: center;
}
.widget-1 {
background-color: #e91e63;
}
.widget-2 {
background-color: #9c27b0;
}
.widget-3 {
background-color: #673ab7;
}
.widget-4 {
background-color: #3f51b5;
}repeat(2, minmax(120px, auto)) 代表建立兩列,每列至少 120px,內容需要更多空間時可以增加高度。gap 則控制網格項目之間的間距,比替每個卡片加一堆 margin 更容易集中管理。
完成通知與頁尾
最後處理通知區域與頁尾。它們的位置已經在 grid-template-areas 裡定義好,現在只要補上外觀即可。
.notifications {
grid-area: notifications;
padding: 12px;
background-color: #8bc34a;
text-align: center;
}
.footer {
grid-area: footer;
padding: 12px;
color: #fff;
background-color: #795548;
text-align: center;
}目前桌面版的版面已經完成。你可以開啟原本的實際範例查看效果:CSS Grid 儀表板範例。接著把視窗縮窄,會看到三欄開始變得擁擠;這就是響應式設計該登場的時候。

桌面版效果。
加上響應式設計
媒體查詢可以依據視窗寬度套用不同樣式。這裡在寬度小於或等於 768px 時,把容器改成單欄,並重新排列具名區域。
@media (max-width: 768px) {
.grid-container {
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"top-nav"
"sidebar"
"main-content"
"extra-content"
"notifications"
"footer";
}
.main-content {
grid-template-columns: 1fr;
}
}注意,改成單欄時,grid-template-areas 的每一列都只有一個名稱,而且順序就是手機上由上到下的順序。這比只把所有元素設成全寬更完整:你同時改了欄數,也清楚指定了內容順序。
內層 .main-content 也改成單欄,讓四張卡片在小螢幕上依序排列。若卡片內容較複雜,還可以再依實際需求調整間距與最小高度;斷點不是魔法數字,而是版面開始不好讀時的提醒。

手機版效果。
常見檢查方式
完成後,可以用瀏覽器的開發者工具檢查 .grid-container。多數現代瀏覽器都能顯示 Grid overlay,協助你確認欄線、區域和間距是否符合預期。
如果區域沒有出現,先依序檢查:
- 容器是否有
display: grid。 grid-template-areas每一列是否有相同數量的儲存格。- 子元素的
grid-area名稱是否和模板完全一致。 - 每個具名區域是否由矩形儲存格組成;不能拼出 L 形區域。
- 媒體查詢內是否真的覆寫了桌面版的欄數與區域模板。
重點整理
這個儀表板範例用到的核心觀念有:
display: grid:建立 Grid 容器,讓直接子元素成為網格項目。grid-template-columns和grid-template-rows:定義欄與列的尺寸。fr:按比例分配可用的剩餘空間。grid-template-areas:用名稱描述整體版面,讓 CSS 讀起來像一張簡單的配置圖。grid-area:把項目放進指定的具名區域。- 巢狀 Grid:在主要內容內再次建立網格,適合排列卡片或小元件。
gap:統一控制網格項目之間的間距。@media:在不同視窗條件下切換欄數與區域配置。
CSS Grid 不會替你決定頁面內容,也不會自動判斷哪張卡片最重要;它負責把你描述的版面可靠地排出來。先從具名區域開始,等你熟悉後,再搭配 Grid line、auto-fit 或 minmax() 做更彈性的元件版面。今天先把咖啡放在桌上,別放進網格裡——那會是另一種溢位問題。
參考資料
- MDN:CSS Grid Layout 的基本概念:說明 Grid 容器、Grid 項目、欄列與
fr單位。 - MDN:使用
grid-template-areas:說明具名區域、區域形狀限制,以及搭配媒體查詢重新配置版面。 - MDN:使用媒體查詢:說明
@media語法與依視窗特徵套用樣式的方法。

