CSS Grid 是 CSS 城中的新生力量,雖然還不被所有瀏覽器完全支持,但它將成為未來布局系統的核心。

網格。一個數字的薄膜。當數據通過計算機傳送時,我試圖想像它們是什麼樣子?船?摩托車?電路就好像高速公路一樣?我一直夢想著能看到像這樣的新世界。然後有一天.. 我進來了。——《创:異世紀》

CSS Grid 簡介

CSS Grid 是使用 CSS 構建佈局的全新方法。

你可以關注 caniuse.com 上的 CSS Grid Layout 頁面 以查找目前支持它的瀏覽器。截至 2019 年 4 月,除了永遠不會支持它的 IE 外,所有主要瀏覽器已經支持這項技術,涵蓋了92%的用戶。

CSS Grid 不是 Flexbox 的競爭對手。它們可以互相協作,構建複雜的布局,因為 CSS Grid 在二維空間(行和列)上工作,而 Flexbox 在單一維度(行或列)上工作。

在 Web 上構建佈局一直是一個復雜的主題。

我不會深入研究這種複雜性的原因,這本身已經是一個複雜的主題,但您可以幸運地認為自己是一個非常幸運的人,因為現在您擁有兩個非常強大且受到良好支持的工具

  • CSS Flexbox
  • CSS Grid

這兩種工具將成為未來 Web 布局的工具。

除非你需要支持舊版的瀏覽器(如 IE8 和 IE9),否則沒有理由再去混淆諸如:

  • 表格布局
  • 浮動
  • 清除浮動的技巧
  • display: table 的技巧

在本指南中,你將找到從對 CSS Grid 一無所知到成為精通使用者所需的全部知識。

基礎知識

在容器元素(可以是 div 或其他標籤)上設置 display: grid 來激活 CSS Grid 佈局。

與彈性盒子相似,你可以在容器上定義一些屬性,並在網格中的每個單獨項目上定義一些屬性。

這些屬性的組合將確定網格的最終外觀。

最基本的容器屬性是 grid-template-columnsgrid-template-rows

grid-template-columns 和 grid-template-rows

這些屬性定義了網格中的列數和行數,並設定了每列/行的寬度。

以下片段定義了一個具有 4 列,每列為 200px 寬度,和 2 行,每行為 300px 高度的網格。

.container {
 display: grid;
 grid-template-columns: 200px 200px 200px 200px;
 grid-template-rows: 300px 300px;
}

一個具有 4 列和 2 行的網格

以下是具有 2 列和 2 行的網格的另一個示例:

.container {
 display: grid;
 grid-template-columns: 200px 200px;
 grid-template-rows: 100px 100px;
}

2列2行的網狀

自動大小

很多時候,你可能會有固定的標頭大小、固定的腳注大小和根據長度彈性改變的主內容。在這種情況下,你可以使用 auto 關鍵字:

.container {
 display: grid;
 grid-template-rows: 100px auto 100px;
}

不同的列和行的大小

在上面的示例中,我們使用相同的列和行的值來創建漂亮的規律的網格。

你可以為每個列/行指定任何值,以創建多種不同的設計:

.container {
 display: grid;
 grid-template-columns: 100px 200px;
 grid-template-rows: 100px 50px;
}

一個不同的列和行的大小的網格

另一個例子:

.container {
 display: grid;
 grid-template-columns: 10px 100px;
 grid-template-rows: 100px 10px;
}

一個不同的列和行的大小的網格

在單元格之間添加間距

除非另外指定,否則單元格之間沒有間距。

您可以使用以下屬性添加間距:

  • grid-column-gap
  • grid-row-gap

或者通過縮寫語法 grid-gap

示例:

.container {
 display: grid;
 grid-template-columns: 100px 200px;
 grid-template-rows: 100px 50px;
 grid-column-gap: 25px;
 grid-row-gap: 25px;
}

一個具有行和列之間間距的網狀

使用縮寫來達到同樣的佈局:

.container {
 display: grid;
 grid-template-columns: 100px 200px;
 grid-template-rows: 100px 50px;
 grid-gap: 25px;
}

在多列和/或多行上添加項目

每個單元格項目都可以選擇佔用多個盒子在行上,並在尊重容器中設置的網格比例的情況下水平或垂直擴展以獲得更多空間。

以下是我們將使用以下屬性來做到這一點:

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end

示例:

.container {
 display: grid;
 grid-template-columns: 200px 200px 200px 200px;
 grid-template-rows: 300px 300px;
}
.item1 {
 grid-column-start: 2;
 grid-column-end: 4;
}
.item6 {
 grid-column-start: 3;
 grid-column-end: 5;
}

編輯一些單元格的尺寸

數字對應於從1開始的分隔每列的垂直線:

數字對應於從1開始的垂直分隔線

相同的原則也適用於 grid-row-startgrid-row-end,只是這次不是佔用更多的列,而是佔用更多的行。

簡寫語法

這些屬性有一個簡寫語法,由以下兩個屬性提供:

  • grid-column
  • grid-row

用法很簡單,這是如何複製上面的佈局:

.container {
 display: grid;
 grid-template-columns: 200px 200px 200px 200px;
 grid-template-rows: 300px 300px;
}
.item1 {
 grid-column: 2 / 4;
}
.item6 {
 grid-column: 3 / 5;
}

使用 grid-area 作為簡寫

當你需要將 grid-columngrid-row 兩者應用於單個元素時,grid-area 屬性可以用作 grid-columngrid-row 的簡寫。相對於:

.item1 {
 grid-row: 1 / 4;
 grid-column: 3 / 5;
}

你可以使用

.item1 {
 grid-area: 1 / 3 / 4 / 5;
}

(grid-row-start / grid-column-start / grid-row-end / grid-column-end)

使用 span

另一種方法是設置起始列/行,並使用 span 來指定它應佔用多少行/列:

.container {
 display: grid;
 grid-template-columns: 200px 200px 200px 200px;
 grid-template-rows: 300px 300px;
}
.item1 {
 grid-column: 2 / span 2;
}
.item6 {
 grid-column: 3 / span 2;
}

span 也可以與非簡寫語法一起使用:

.item1 {
 grid-column-start: 2;
 grid-column-end: span 2;
}

您也可以在起始屬性上使用 span。在這種情況下,結束位置將被用作參考,而 span 則向“後”計數:

.item1 {
 grid-column-start: span 2;
 grid-column-end: 3;
}

更多網格配置

使用分數

在某些情況下,指定每個列或行的確切寬度不是理想的。

分數是空間的一個單位。

下面的示例將網格分為 3 列,每個列的寬度相同,佔用可用空間的 1/3。

.container {
 grid-template-columns: 1fr 1fr 1fr;
}

使用百分比和 rem

您也可以使用百分比,混合和匹配分數、像素、rem 和百分比:

.container {
 grid-template-columns: 3rem 15% 1fr 2fr
}

使用 repeat()

repeat() 是一個特殊的函數,它接受一個數字,表示每個行/列將重複的次數,以及每個行/列的長度。

如果每列都有相同的寬度,則可以使用這種語法指定佈局。

例如:

.container {
 grid-template-columns: repeat(4, 100px);
}

這將創建 4 個具有相同寬度的列。

或者使用分數:

.container {
 grid-template-columns: repeat(4, 1fr);
}

為行指定最小寬度

常見的用法是:當調整窗口大小時,側邊欄不會收縮到小於某個像素值。

以下是一個示例,其中側邊欄佔用屏幕的 1/4,並且不小於 200px:

.container {
 grid-template-columns: minmax(200px, 3fr) 9fr;
}

您也可以只設置最大值,使用 auto 關鍵字:

.container {
 grid-template-columns: minmax(auto, 50%) 9fr;
}

或者只設置最小值:

.container {
 grid-template-columns: minmax(100px, auto) 9fr;
}

使用 grid-template-areas 定位元素

默認情況下,元素根據在 HTML 結構中的順序在網格中定位。

使用 grid-template-areas,您可以定義模板區域,在網格中移動它們,並且還可以將項目放置在多個行/列上,而不是使用 grid-column

以下是一個示例:

<div class="container">
 <main>
 ...
 </main>
 <aside>
 ...
 </aside>
 <header>
 ...
 </header>
 <footer>
 ...
 </footer>
</div>
.container {
 display: grid;
 grid-template-columns: 200px 200px 200px 200px;
 grid-template-rows: 300px 300px;
 grid-template-areas:
 "header header header header"
 "sidebar main main main"
 "footer footer footer footer";
}
main {
 grid-area: main;
}
aside {
 grid-area: sidebar;
}
header {
 grid-area: header;
}
footer {
 grid-area: footer;
}

儘管元素的原始順序不同,但是它們根據 grid-template-areas 的定義放置,具體取決於與之關聯的 grid-area 屬性。

在模板區域中添加空單元格

您可以在 grid-template-areas 中使用點 . 來設置一個空的單元格:

.container {
 display: grid;
 grid-template-columns: 200px 200px 200px 200px;
 grid-template-rows: 300px 300px;
 grid-template-areas:
 ". header header ."
 "sidebar . main main"
 ". footer footer .";
}

使用網格填充頁面

您可以使用 fr 將網格伸展填充到整個頁面:

.container {
 display: grid;
 height: 100vh;
 grid-template-columns: 1fr 1fr 1fr 1fr;
 grid-template-rows: 1fr 1fr;
}

示例:標題、側邊欄、內容和頁腳

這是一個使用 CSS Grid 創建網站布局的簡單例子,該布局提供頂部的標題,左側帶有側邊欄和右側的內容,然後是頁腳。

布局示例

以下是標記:

<div class="wrapper">
 <header>Header</header>
 <article>
 <h1>Welcome</h1>
 <p>Hi!</p>
 </article>
 <aside><ul><li>Sidebar</li></ul></aside>
 <footer>Footer</footer>
</div>

以下是 CSS:

header {
 grid-area: header;
 background-color: #fed330;
 padding: 20px;
}
article {
 grid-area: content;
 background-color: #20bf6b;
 padding: 20px;
}
aside {
 grid-area: sidebar;
 background-color: #45aaf2;
}
footer {
 padding: 20px;
 grid-area: footer;
 background-color: #fd9644;
}
.wrapper {
 display: grid;
 grid-gap: 20px;
 grid-template-columns: 1fr 3fr;
 grid-template-areas:
 "header header"
 "sidebar content"
 "footer footer";
}

我添加了一些顏色使它看起來更漂亮,但基本上它為每個不同的標籤分配了一個 grid-area 名稱,該名稱在 .wrappergrid-template-areas 屬性中使用。

當佈局更小時,我們可以使用媒體查詢將側欄放在內容下方:

@media (max-width: 500px) {
 .wrapper {
 grid-template-columns: 4fr;
 grid-template-areas:
 "header"
 "content"
 "sidebar"
 "footer";
 }
}

查看以上代碼 CodePen 上的示例

總結

這些是 CSS Grid 的基礎知識。這個簡介中還有很多東西沒有包括在內,但我希望它非常簡單,以便您可以開始使用這個新的佈局系統,而不讓它變得困難。