重點摘要
如果熟悉 Flexbox,Grid 會感到熟悉。Rachel Andrew 維護一個CSS 格狀專用網站,可協助您快速上手。Google Chrome 現已支援格狀檢視畫面。
Flexbox?格狀檢視?
過去幾年來,CSS Flexbox 的使用越來越普及,瀏覽器支援看起來也很不錯 (除非您是必須支援 IE9 以下版本的弱勢族群)。Flexbox 能簡化大量複雜的版面配置工作,例如元素之間保持平衡間距、由上至下的版面配置,或是 CSS 精靈的神奇脈動:垂直置中。
![無法對齊多個 Flexbox 容器中的元素。](https://cdn.statically.io/img/developer.chrome.google.cn/static/docs/css-ui/css-grid/image/theres-way-align-eleme-e823875eb6d43.png?hl=zh-tw)
不過沒錯,螢幕通常會有第二個需要擔心的尺寸。很遺憾地,自行調整元素大小時,只使用 Flexbox 無法「同時」使用垂直和水平節奏。此時 CSS 網格就能派上用場。
CSS Grid 一直在開發階段,超過 5 年在大多數瀏覽器中都設有標記,而且在互通性方面花費了額外時間,以避免 Flexbox 這類錯誤啟動的問題。因此,如果您使用格線在 Chrome 中實作版面配置,在 Firefox 和 Safari 中也可能會看到相同的結果。在本文撰寫期間,Microsoft 的 Edge 的 Edge 實作已過時 (與 IE11 中現有的內容相同),且更新狀態為「考慮中」。
儘管概念和語法中的相似之處,但請勿將 Flexbox 和 Grid 視為競爭的版面配置技術。格線在兩種維度中排列,Flexbox 則以一個維度排列。同時使用這兩種工具可以產生協同效應。
定義格線
如想瞭解格線的個別屬性,我非常推薦 Raachel Andrew 的「範例格狀檢視畫面」或 CSS Tricks 的一覽表。如果您熟悉 Flexbox,則應瞭解許多屬性及其意義。
以下來看看標準的 12 欄格狀版面配置。傳統的 12 欄版面配置廣受好評,因為數字 12 可由 2、3、4 和 6 整除,因此在許多設計上都能派上用場。讓我們實作這個版面配置:
![無法對齊多個 Flexbox 容器中的元素。](https://cdn.statically.io/img/developer.chrome.google.cn/static/docs/css-ui/css-grid/image/theres-way-align-eleme-246a82e6f78fc.png?hl=zh-tw)
首先來介紹標記程式碼:
<!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 過度混亂。為了簡單起見,我們將以下列方式實作版面配置:
![簡化版面配置範例](https://cdn.statically.io/img/developer.chrome.google.cn/static/docs/css-ui/css-grid/image/simplified-layout-example-9cd17f74b5ac9.png?hl=zh-tw)
頁首和頁尾的寬度會變動,內容在這兩種尺寸中都是變數。導覽在兩個維度中都會變動,但我們會強制規定最小寬度為 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-width
和 max-width
。)寬度下限如先前討論的 200 像素寬度上限為 3fr
。fr
是格線專用的單元,可讓您將可用空間分配給格線元素。fr 可能代表「片段單位」,但也可能表示很快就有空房。這裡的值表示兩個資料欄會填滿整個螢幕,但內容欄寬度將一律為導覽欄的 3 倍 (前提是導覽欄寬度大於 200 像素)。
雖然格線項目的「位置」不正確,但資料列和資料欄的「大小」行為都正常運作,並產生我們希望達到以下目標的行為:
放置商品
格線最強大的功能之一,就是能夠在不考慮 DOM 順序的情況下放置項目。(雖然螢幕閱讀器可瀏覽 DOM,但強烈建議您留意元素重新排序的方式,以便妥善存取)。如果沒有手動配置,元素會以 DOM 順序排列,由左至右並由上而下。每個元素都會佔用一個「儲存格」。您可以使用 grid-auto-flow
變更格線填入的順序。
那麼該如何放置元素呢?基本上,放置格線項目最簡單的方式,就是定義這些項目所涵蓋的欄和資料列。格線提供兩種執行此操作的語法: 您在定義起點和終點的第一個語法中在第二個範例中,您要定義起點和時距:
header {
grid-column: 1 / 3;
}
nav {
grid-row: 2 / span 2;
}
![手動設定廣告插播時間點](https://cdn.statically.io/img/developer.chrome.google.cn/static/docs/css-ui/css-grid/image/manual-placement-d741d497e8f91.png?hl=zh-tw)
我們要將標題從第一欄開始,到第三欄之前結束。 導覽應從第二列開始,總共橫跨 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 的寶貴資源。許多人都以為 Grid 是網頁設計的創新步驟,而現在 Chrome 已預設啟用它,因此您可以立即開始使用。