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-columns
和 grid-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;
}
以下是具有 2 列和 2 行的網格的另一個示例:
.container {
display: grid;
grid-template-columns: 200px 200px;
grid-template-rows: 100px 100px;
}
自動大小
很多時候,你可能會有固定的標頭大小、固定的腳注大小和根據長度彈性改變的主內容。在這種情況下,你可以使用 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開始的分隔每列的垂直線:
相同的原則也適用於 grid-row-start
和 grid-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-column
和 grid-row
兩者應用於單個元素時,grid-area
屬性可以用作 grid-column
和 grid-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
名稱,該名稱在 .wrapper
的 grid-template-areas
屬性中使用。
當佈局更小時,我們可以使用媒體查詢將側欄放在內容下方:
@media (max-width: 500px) {
.wrapper {
grid-template-columns: 4fr;
grid-template-areas:
"header"
"content"
"sidebar"
"footer";
}
}
查看以上代碼 CodePen 上的示例。
總結
這些是 CSS Grid 的基礎知識。這個簡介中還有很多東西沒有包括在內,但我希望它非常簡單,以便您可以開始使用這個新的佈局系統,而不讓它變得困難。