CSS 格線 - 表格版面配置已恢復。適時出現,抓住時機

TL;DR

如果您熟悉 Flexbox,Grid 應該會讓您覺得熟悉。Rachel Andrew 維護一個CSS 格狀專用網站,可協助您快速上手。網格功能現已在 Google Chrome 中推出。

Flexbox?格狀檢視?

過去幾年,CSS Flexbox 已廣泛使用,且瀏覽器支援情況也相當良好 (除非您是需要支援 IE9 以下版本的可憐蟲)。Flexbox 能簡化大量複雜的版面配置工作,例如元素之間保持平衡間距、由上至下的版面配置,或 CSS 精靈的神奇脈動:垂直置中。

無法在多個 Flexbox 容器中對齊元素。

不過沒錯,螢幕通常會有第二個需要擔心的尺寸。很遺憾地,自行調整元素大小時,只使用 Flexbox 無法「同時」使用垂直和水平節奏。這時 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 整除,因此可用於許多設計。讓我們實作這個版面配置:

無法在多個 Flexbox 容器中對齊元素。

我們先從標記碼開始:

<!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 中,我們使用彈性擴充和彈性縮小,但在 Grid 中還是有些許不同:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
}

定義了 2 個欄位。第一欄是使用 minmax() 函式定義,該函式會採用 2 個值:該曲目的最小和最大大小。(就像 min-widthmax-width 一樣)。如先前所述,最小寬度為 200 像素。寬度上限為 3frfr 是專屬於格線的單位,可讓您將可用空間分配給格線元素。fr 可能是「fraction unit」的縮寫,但也可能代表 soon free unit。這裡的值表示兩個欄都會擴大填滿畫面,但內容欄的寬度一律是導覽欄的 3 倍 (前提是導覽欄的寬度必須大於 200 像素)。

雖然格線項目的「位置」不正確,但資料列和資料欄的「大小」會正常運作,並產生我們希望達到以下目標的行為:

放置項目

Grid 最強大的功能之一,就是可以不考慮 DOM 順序來放置項目。雖然螢幕閱讀器可瀏覽 DOM,但強烈建議您留意元素重新排序的方式,以便妥善存取。如果未完成手動放置作業,系統會依 DOM 順序將元素放置在格狀區塊中,並以由左至右、由上至下的方式排列。每個元素都會佔用一個儲存格。您可以使用 grid-auto-flow 變更填入格線的順序。

那麼,我們該如何放置元素?放置格線項目最簡單的方法,就是定義它們涵蓋哪些欄和列。格線提供兩種執行此操作的語法: 您在定義起點和終點的第一個語法中在第二個範例中,您要定義起點和時距:

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
手動設定廣告插播時間點

我們要將標題從第一欄開始,到第三欄之前結束。 導覽應從第二列開始,總共橫跨 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 能簡化網頁設計。她甚至在書上寫了一本。她的網站「Grid By Example」是熟悉 Grid 的寶貴資源。許多人認為格線是網頁設計的革命性一步,現在 Chrome 已預設啟用格線,您可以立即開始使用。