前言
在上一篇文章中,我們了解了 Flex 布局系統的強大功能和靈活性,其能夠幫我們輕松地控制和對齊頁面中的元素
然而,在實際的網頁設計中,我們經常會遇到更加復雜的布局需求,例如建立多列、多行的網格結構,為了解決這些需求, Grid 布局應運而生
Grid 布局是一種 二維 布局系統,它不僅能夠像 Flex 一樣處理單軸上的布局,還能同時處理 行和列 ,從而實作更加復雜和精確的布局控制,無論是簡單的頁面排版,還是復雜的網頁設計, Grid 布局都能提供強大的支持
Grid布局
Grid 布局,也稱 網格布局 ,不同於 Flex 針對軸線的 一維布局 , Grid 是一個 二維 的布局,其將 計畫 劃分在 行 和 列 中, 容器 就像一個 網格 一樣, 計畫 就是一個個單元格,其能實作實作更加精細和復雜的設計
Grid 布局是由W3C在 2011 年首次提出的,於 2014 年,釋出了關於第一個工作草案
到 2016 年, Grid 布局規範進入候選推薦階段,最終在 2017 年,正式成為W3C推薦標準,並在主流瀏覽器中得到了廣泛支持
其相容性如下(主流瀏覽器均已支持):
基本概念
任何元素均可定義為 Grid 容器,使用 Grid布局 ,只需設定元素的 display 內容為 grid 或 inline-grid 即可,如下:
定義了 Grid 布局的元素,稱為 容器 (container),其直接子元素會自動按 網格 排列,稱為 計畫 (item)
註意,設Grid後,容器內計畫的float、display: inline-block、display: table-cell、vertical-align和column-*等設定都將失效
行和列
容器 內水平區域稱為 行 ,垂直區域稱為 列
行 與 列 交叉的區域稱為 單元格 , 計畫 就按順序存放在一個個單元格內
格線
劃分單元格的線稱為 格線 ,水平的格線劃分 行 ,垂直的格線劃分 列
區域
由一個或多個 計畫 組成的矩形區域稱為 Grid區域 (grid areas)
容器內容
下列內容主要使用於 容器 上
grid-template-rows|columns
該內容主要用於定義 網格 的 行 和 列 (幾行,各行寬;幾列,各列寬等)
其是 grid-template-rows 和 grid-template-columns 內容的簡寫形式,形式如下:
grid-template-rows 內容定義每一行的行寬, grid-template-columns 內容定義每一列的列寬
如下,定義一個3×3的 Grid容器 ,且每個 計畫 的寬高均為 100px
有時,我們並不能確定某行(列)的寬度,或行(列)數量較多時,按這種形式寫比較復雜,所以,CSS提供了一些 函式 或 關鍵字 ,可方便我們的設定
該 函式 用於 簡化重復值 ,形式如下:
效果與上側實作一致
repeat()接收兩個參數,第一個參數列示 重復的次數 ,第二個參數列示 重復的內容
該 關鍵字 主要用於表示 比例 關系,其為 fraction (片段)的縮寫
上側container-1表示,將 容器 均分為三列,container-2表示,將 容器 按1:2:3的比例分為三列
該 函式 用於表示一個 長度範圍 ,其接收兩個參數:一個最小值(min)和一個最大值(max),表示長度在 [min, max] 內,數值是任何有效的CSS長度值、百分比或 auto
上側程式碼表示將 容器 分為三列,左右兩列固定寬度,中間的列最小寬度不小於 72px ,最大寬度不大於 1fr
該 關鍵字 表示由瀏覽器自己決定長度
上側程式碼中,第一列會占據 容器 剩余寬度,除非列內單元格內容設定了 min-width ,且這個值大於最大寬度
該 關鍵字 用於實作 自動填充 ,有時候, 計畫 (單元格)的大小是確定的,但 容器 的大小不確定,因此我們無法確定每一行(列)可容納的 計畫數 ,此時,我們希望每一行(列)可以盡可能多地容納 計畫 ,即可用 auto-fill
上側的程式碼,我們對 列 設定了 auto-fill ,此時 容器 會按每列 100px 的寬度,自動填充列,直到不可容下更多 列 為止
與 auto-fill 類似的,還有一個 auto-fit 關鍵字
auto-fill與auto-fit的區別:
auto-fill會在 容器 中盡可能多地填充列或行,不管 單元格 是否有內容
其 特點 為:
自動填充列或行,盡量多地建立網格軌域
即使某些網格單元沒有內容,也會分配空間
auto-fit當 容器 寬度增延長,會調整現有列的大小,而不是增加新的空列
其 特點 為:
自動適應列或行,現有列會根據容器大小調整
空列會被折疊,不占用額外的空間
一般情況下,兩種基本無差別,只有當 容器 足夠寬,足以在一行容納所有 單元格 ,並且單元格寬度 不固定 ,才會有差異
舉個栗子
當 容器 寬度足夠富余時,fill 容器 會盡可能多地容納列,每列100px,而fit容器會優先分配空間給已有列,每列 1fr
在 Grid 布局內,允許指定每一根格線的名字,方便以後的參照
主要方式為使用 方括弧 ,在 grid-template-columns 內容和 grid-template-rows 內容裏面定義,如:
上側程式碼中,定義了一個 3×3 的網格,所以有 4 根列線與 4 根行線,上側的[]內的值即為每根線的名稱,如: c1
同一根線可以有多個名稱,只需定義在同一個 方括弧 內,用 空格 隔開,如: [c1 column1]
gap
該內容用於定義 行與行 之間、 列與列 之間的 間距 ,是 row-gap 和 column-gap 的簡寫,形式如下:
接收一個或兩個值,當只有一個時,表示行列間距均為該值
row-gap 內容用於設定 行與行 之間的間距
column-gap 內容用於設定 列與列 之間的間距
上側程式碼大致效果如下(橙色部份即為間距):
過去的 gap 名稱為 grid-gap ,該名稱首次於 2017 年在 CSS Grid Layout Module Level 1 中被引入,但在 2018 年提出的 CSS Box Alignment Module Level 3 被重新命名為 gap ,同時適用於Grid和Flex
grid-template-areas
該內容用於定義 網格區域 ,對網格區域進行 命名 ,後續可使用命名的網格區域進行布局,如:
上側程式碼定義了一個 3×3 的網格,共有 9 個單元格,分別命名為 a-i ,共有 9 個區域
一個區域,可以由 一個或多個 單元格組成,當有多個單元格時,則用相同名稱即可,如:
相同名稱的單元格會合並為一個區域
如某些單元格不想命名,無需利用處理,用.點占位即可,如:
上側的程式碼命名了 4 個區域,中間的點表示該單元格不屬於任何區域
使用場景
簡單直觀地定義一個頁面的布局
當你使用 grid-template-areas 定義網格區域時,Grid會自動生成與這些區網域名稱稱相關的命名格線
命名格線的格式如下:
area-name-start:區域的起始線
area-name-end:區域的結束線
例如,如果定義了一個名為 header 的區域,會自動生成以下格線:
header-start
header-end
grid-auto-flow
該內容用於定義自動放置的 計畫 的布局順序,其決定了當 容器 中的 計畫 沒有明確指定位置時,瀏覽器如何自動放置它們,其可能值為:
row 的放置順序是 先行後列 ,即先放滿第一行,再放第二行,效果如下:
column 的放置順序是 先列後行 ,即先放滿第一列,再放第二列,效果如下:
dense 用於與 row 或 column 搭配使用,使 容器 更 緊湊 地排列 計畫
如下,為無 dense 情況下的排列情況,會存在一些空白沒有利用:
當搭配 dense 後,空白會被盡可能地利用,情況如下:
*-items
justify-items 內容設定單元格內 計畫 的水平對齊效果(左中右)
align-items 內容設定單元格內 計畫 的垂直對齊效果(上中下)
兩個內容均有如下取值:
語法如下:
place-items 內容是 align-items 內容和 justify-items 內容的合並簡寫形式,形式如下:
接收兩個值,用空格隔開,第二個值可省略,如省略,則表示與第一個值相同
*-content
justify-content 內容用於控制整個內容區域在 容器 內的水平對齊(左中右)
align-content 內容用於控制整個內容區域在 容器 內的垂直對齊(上中下)
兩個內容取值均相同,如下:
place-content 內容是 align-content 內容和 justify-content 內容的合並簡寫形式,語法如下:
如果省略第二個值,則會假定第二個值與第一個值相同
grid-auto-*
grid-auto-columns 和 grid-auto-rows 用於定義在 Grid 布局中隱式建立的列和行的大小
其語法如下:
<track-size> 可以是任何有效的 CSS 尺寸值,如 px 、 % 、 fr 、 auto 等
舉個栗子
比如,我們建立了一個 3×3 的網格 容器 ,但我們的 計畫 不止 9 個(比如有 11 個),或者有些計畫指定位置超出 3×3 的範圍(比如設定在 (4, 2) 位置),此時,瀏覽器會自動生成多余的網格,用於放置 計畫
在上側程式碼中,任何隱式建立的行(即超過顯式定義的三行的行)將被設定為 50px 高
grid-template
該內容是 grid-template-rows 、 grid-template-columns 和 grid-template-areas 的合並簡寫形式
舉個栗子
grid
grid 是 grid-template-rows 、 grid-template-columns 、 grid-template-areas 、 grid-auto-rows 、 grid-auto-columns 、 grid-auto-flow 六個內容的合並簡寫形式
基本語法
簡寫形式可以簡化書寫,但同時也降低了程式碼可讀性,不建議使用
計畫內容
主要作用域 計畫 上的內容
grid-column|row
grid-column 是一個簡寫內容,用於定義 計畫 在網格中的水平位置,其結合了以下兩個內容:
基本語法
<grid-line> 可以是行號、命名的格線、 span 關鍵字加行數,或者 auto
<grid-area> 是透過 grid-template-areas 定義的網格區網域名稱
grid-row 也是一個簡寫內容,用於定義 計畫 在網格中的垂直位置,其結合了以下兩個內容:
使用與 grid-column 一致
span 關鍵字,後接空格跟一個數位,表示跨越(占據)多少行(列)
grid-area
該內容用於指定 計畫 放置在哪一區域
基本語法
<grid-area-name> 為 grid-template-areas 定義的區網域名稱稱
其還有另一種語法:
可用作 grid-row-start 、 grid-column-start 、 grid-row-end 、 grid-column-end 的合並簡寫形式
*-self
justify-self 內容用於設定 計畫 在單元格內的水平對齊方式,跟 justify-items 內容的用法類似,但只作用於單個計畫
align-self 內容用於設定網格計畫在單元格內的垂直對齊方式,跟 align-items 內容的用法類似,但只作用於單個計畫
兩者可能取值均相同,如下:
place-self 是一個簡寫內容,用於同時設定 justify-self 和 align-self 的值,形式如下:
如果省略第二個值,則第二個值與第一個值相等
特點
二維布局系統 :支持同時定義行和列,適合復雜布局
顯式與隱式網格 :可以明確定義網格,同時自動建立額外的網格以容納計畫
強大的對齊與定位控制 :透過內容如 justify-items 、 align-items 、 justify-content 和 align-content ,可以精確控制計畫在網格中的位置和對齊方式
網格間距和分區 :支持定義網格之間的間距,並能夠劃分為命名的網格區域,便於布局管理和維護
響應式設計支持 :可以輕松地調整網格的大小和布局,以適應不同的螢幕尺寸和裝置
配合 Flexbox 使用 :與 Flex 結合使用,可以實作更復雜的布局需求,靈活而強大
使用場景
復雜的布局需求 :適合需要精確控制多個計畫在網格中位置和大小的復雜布局,如新聞網站的多欄布局或者儀表板的網格化布局
網格化設計 :對於需要將頁面劃分為多個命名區域並對其進行管理的設計,如大型網頁或應用程式的板塊化設計
響應式設計 :能夠根據不同的螢幕尺寸和裝置自動調整布局,使得設計在行動裝置和桌面上都能夠優雅地呈現
比如,嗶哩嗶哩推薦的視訊列表就是用 grid 實作的, Grid 是一個非常強大的布局工具,特別適合於需要更高級和復雜布局需求的現代網頁設計和開發