TL;DR
如果您熟悉 Flexbox,Grid 應該會讓您覺得熟悉。Rachel Andrew 維護一個專門提供 CSS 格線資訊的優質網站,協助您開始使用。網格功能現已在 Google Chrome 中推出。
Flexbox?格狀檢視畫面?
過去幾年,CSS Flexbox 已廣泛使用,且瀏覽器支援情況也相當良好 (除非您是需要支援 IE9 以下版本的倒楣鬼)。Flexbox 讓許多複雜的版面配置工作變得更簡單,例如元素之間的等距離間距、由上而下的版面配置,或是 CSS 魔法師的聖杯:垂直置中。
不過,螢幕通常還有另一個需要注意的維度。很遺憾,除了自行處理元素大小以外,您無法只使用彈性容器來同時處理垂直和水平節奏。這時 CSS 格線就能派上用場。
CSS 格線一直在開發中,在大多數瀏覽器中已設為標記超過 5 年,我們也花了額外時間處理互通性問題,以免像 Flexbox 一樣推出時出現錯誤。因此,如果您在 Chrome 中使用 Grid 實作版面配置,在 Firefox 和 Safari 中也會獲得相同的結果。在撰寫本文時,Microsoft Edge 的 Grid 實作方式已過時 (與 IE11 中現有的相同),且更新處於「審查中」。
雖然 Flexbox 和 GridLayout 在概念和語法上有相似之處,但請勿將 Flexbox 和 GridLayout 視為競爭的版面配置技巧。格線會以兩個維度排列,而 Flexbox 則會以一個維度排列。兩者搭配使用時,可發揮相輔相成的作用。
定義格線
如要熟悉 Grid 的個別屬性,我誠摯推薦 Rachel Andrew 的 Grid By Example 或 CSS Tricks 的 Cheat Sheet。如果您熟悉 Flexbox,應該會對許多屬性及其含義感到熟悉。
我們來看看標準的 12 欄格格線版面配置。經典的 12 欄版面配置很受歡迎,因為 12 這個數字可被 2、3、4 和 6 整除,因此可用於許多設計。讓我們實作這個版面配置:
我們先從標記碼開始:
<!DOCTYPE html>
<body>
<header></header>
<nav></nav>
<main></main>
<footer></footer>
</body>
在樣式表中,我們會先擴展 body
,讓其涵蓋整個檢視區,並將其轉換為格線容器:
html, body {
width: 100vw;
min-height: 100vh;
margin: 0;
padding: 0;
}
body {
display: grid;
}
我們現在使用 CSS 格線。正確無誤!
接下來,我們要實作網格的列和欄。我們可以在模擬圖中實作所有 12 個資料欄,但由於我們並未使用每個資料欄,因此這樣做會讓 CSS 不必要地雜亂。為求簡單起見,我們會以這種方式實作版面配置:
頁首和頁尾的寬度會變動,內容的兩個維度也會變動。導覽列也會在兩個維度中變化,但我們會將其寬度設為 200 像素的最低值。(原因為何?當然,這是為了展示 CSS 格線的功能)。
在 CSS 格線中,一組欄和列稱為「軌道」。我們先定義第一組軌道 (即資料列):
body {
display: grid;
grid-template-rows: 150px auto 100px;
}
grid-template-rows
會接收定義個別資料列的大小序列。在本例中,我們將第一列的高度設為 150 像素,最後一列則設為 100 像素。中間一列設為 auto
,表示會調整至所需高度,以容納該列中的格狀項目 (格狀容器的子項)。由於身體會延伸至整個檢視區,因此包含內容的軌道 (上圖中的黃色) 至少會填滿所有可用空間,但在必要時會擴大 (並使文件捲動)。
我們希望在欄位方面採用更具彈性的做法:我們希望導覽和內容都能放大 (和縮小),但導覽欄位不得縮小至 200 像素以下,且內容必須大於導覽欄位。在 Flexbox 中,我們會使用 flex-grow 和 flex-shrink,但在 GridLayout 中,情況稍有不同:
body {
display: grid;
grid-template-rows: 150px auto 100px;
grid-template-columns: minmax(200px, 3fr) 9fr;
}
我們定義了 2 個資料欄。第一欄是使用 minmax()
函式定義,該函式會採用 2 個值:該曲目的最小和最大大小。(就像 min-width
和 max-width
一樣)。如先前所述,寬度不得低於 200 像素。寬度上限為 3fr
。fr
是專屬於格線的單位,可讓您將可用空間分配給格線元素。fr 可能是「fraction unit」的縮寫,但也可能代表「free unit soon」。這裡的值表示兩個欄都會擴大填滿畫面,但內容欄的寬度一律是導覽欄的 3 倍 (前提是導覽欄的寬度必須大於 200 像素)。
雖然目前格狀項目的位置不正確,但列和欄的大小運作正常,並產生我們預期的行為:
放置項目
Grid 最強大的功能之一,就是可以不考慮 DOM 順序來放置項目。(不過,由於螢幕閱讀器會瀏覽 DOM,因此我們強烈建議您留意如何重新排序元素,以便確保適當的無障礙存取能力)。如果未完成手動放置作業,系統會依 DOM 順序將元素放置在格狀區塊中,並以由左至右、由上至下的方式排列。每個元素都會佔用一個儲存格。您可以使用 grid-auto-flow
變更填入格線的順序。
那麼,我們該如何放置元素?放置格線項目最簡單的方法,就是定義它們涵蓋哪些欄和列。Grid 提供兩種語法可用於這項操作:在第二個函式中,您會定義起點和跨度:
header {
grid-column: 1 / 3;
}
nav {
grid-row: 2 / span 2;
}
我們希望標頭從第一欄開始,並在第 3 欄前面結束。導覽列應從第二列開始,總共跨越 2 列。
從技術層面來說,我們已完成版面配置的實作,但我想向您展示 Grid 提供的幾項便利功能,方便您更輕鬆地進行放置。第一個功能是,您可以為音軌邊框命名,並使用這些名稱進行放置:
body {
display: grid;
grid-template-rows: 150px [nav-start] auto 100px [nav-end];
grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
grid-column: header-start / header-end;
}
nav {
grid-row: nav-start / nav-end;
}
上述程式碼會產生與先前程式碼相同的版面配置。
更強大的功能是可為格狀圖中的整個區域命名:
body {
display: grid;
grid-template-rows: 150px auto 100px;
grid-template-columns: minmax(200px, 3fr) 9fr;
grid-template-areas: "header header"
"nav content"
"nav footer";
}
header {
grid-area: header;
}
nav {
grid-area: nav;
}
grid-template-areas
會採用以空格分隔的名稱字串,方便開發人員為每個儲存格命名。如果兩個相鄰的儲存格名稱相同,就會合併至同一區域。這樣一來,您就能為版面配置程式碼提供更多語意,並讓媒體查詢更直覺。同樣地,這個程式碼會產生與先前相同的版面配置。
還有其他問題嗎?
是的,是的,單一篇網誌文章無法涵蓋太多內容。Rachel Andrew 也是 GDE,也是 CSS 工作小組的邀請專家,從一開始就與他們合作,確保 Grid 能簡化網頁設計。她甚至寫了一本書。她的網站「格狀檢視範例」是熟悉格狀檢視的寶貴資源。許多人認為格線是網頁設計的革命性一步,現在 Chrome 已預設啟用格線,您可以立即開始使用。