當前位置: 華文世界 > 科技

從零開始的Grid布局掌握

2024-09-04科技

前言

在上一篇文章中,我們了解了 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()
  • 函數 用於 簡化重復值 ,形式如下:

    效果與上側實作一致

    repeat()接收兩個參數,第一個參數列示 重復的次數 ,第二個參數列示 重復的內容

  • fr
  • 關鍵字 主要用於表示 比例 關系,其為 fraction (片段)的縮寫

    上側container-1表示,將 容器 均分為三列,container-2表示,將 容器 按1:2:3的比例分為三列

  • minmax()
  • 函數 用於表示一個 長度範圍 ,其接收兩個參數:一個最小值(min)和一個最大值(max),表示長度在 [min, max] 內,數值是任何有效的CSS長度值、百分比或 auto

    上側程式碼表示將 容器 分為三列,左右兩列固定寬度,中間的列最小寬度不小於 72px ,最大寬度不大於 1fr

  • auto
  • 關鍵字 表示由瀏覽器自己決定長度

    上側程式碼中,第一列會占據 容器 剩余寬度,除非列內單元格內容設定了 min-width ,且這個值大於最大寬度

  • auto-fill
  • 關鍵字 用於實作 自動填充 ,有時候, 專案 (單元格)的大小是確定的,但 容器 的大小不確定,因此我們無法確定每一行(列)可容納的 專案數 ,此時,我們希望每一行(列)可以盡可能多地容納 專案 ,即可用 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 :專案按照列的順序放置
  • row dense :按行順序放置專案,並盡可能緊湊地填充空白區域
  • column dense :按列順序放置專案,並盡可能緊湊地填充空白區域
  • row 的放置順序是 先行後列 ,即先放滿第一行,再放第二行,效果如下:

    column 的放置順序是 先列後行 ,即先放滿第一列,再放第二列,效果如下:

    dense 用於與 row 或 column 搭配使用,使 容器 更 緊湊 地排列 專案

    如下,為無 dense 情況下的排列情況,會存在一些空白沒有利用:

    當搭配 dense 後,空白會被盡可能地利用,情況如下:

    *-items

    justify-items 內容設定單元格內 專案 的水平對齊效果(左中右)

    align-items 內容設定單元格內 專案 的垂直對齊效果(上中下)

    兩個內容均有如下取值:

  • stretch :( 預設值 )網格項在每個單元格中拉伸以填滿單元格(如果可能)
  • start :網格項在每個單元格的起始位置對齊(左對齊)
  • end :網格項在每個單元格的結束位置對齊(右對齊)
  • center :網格項在每個單元格的中央對齊
  • 語法如下:

    place-items 內容是 align-items 內容和 justify-items 內容的合並簡寫形式,形式如下:

    接收兩個值,用空格隔開,第二個值可省略,如省略,則表示與第一個值相同

    *-content

    justify-content 內容用於控制整個內容區域在 容器 內的水平對齊(左中右)

    align-content 內容用於控制整個內容區域在 容器 內的垂直對齊(上中下)

    兩個內容取值均相同,如下:

  • start :內容在容器的起始位置對齊
  • end :內容在容器的結束位置對齊
  • center :內容在容器的中央對齊
  • stretch :內容在容器中拉伸以填滿可用空間
  • space-between :內容行(列)之間平均分配空間,第一行(列)與容器的起始位置對齊,最後一行(列)與容器的結束位置對齊
  • space-around :內容行(列)之間的空間平均分配,每一行(列)周圍的間距相等
  • space-evenly :內容行(列)之間以及內容與容器邊緣之間的空間平均分配
  • 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 的合並簡寫形式

    舉個栗子

  • 第一行的高度為 100px ,第二行為 200px ,第三行為 100px
  • 第一列的寬度為 1fr ,第二列為 2fr ,第三列為 1fr
  • 定義了三個區域: header 、 sidebar 和 content
  • 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-column-start :定義專案的水平初始位置
  • grid-column-end :定義專案的水平結束位置
  • 基本語法

    <grid-line> 可以是行號、命名的格線、 span 關鍵字加行數,或者 auto

    <grid-area> 是透過 grid-template-areas 定義的網格區網域名稱

    grid-row 也是一個簡寫內容,用於定義 專案 在網格中的垂直位置,其結合了以下兩個內容:

  • grid-row-start :定義專案的垂直初始位置
  • grid-row-end :定義專案的垂直結束位置
  • 使用與 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 內容的用法類似,但只作用於單個專案

    兩者可能取值均相同,如下:

  • stretch :( 預設值 )專案在單元格內拉伸以填滿單元格
  • start :專案在單元格的起始邊對齊
  • end :專案在單元格的結束邊對齊
  • center :專案在單元格的中心對齊
  • place-self 是一個簡寫內容,用於同時設定 justify-self 和 align-self 的值,形式如下:

    如果省略第二個值,則第二個值與第一個值相等

    特點

    二維布局系統 :支持同時定義行和列,適合復雜布局

    顯式與隱式網格 :可以明確定義網格,同時自動建立額外的網格以容納專案

    強大的對齊與定位控制 :透過內容如 justify-items 、 align-items 、 justify-content 和 align-content ,可以精確控制專案在網格中的位置和對齊方式

    網格間距和分區 :支持定義網格之間的間距,並能夠劃分為命名的網格區域,便於布局管理和維護

    響應式設計支持 :可以輕松地調整網格的大小和布局,以適應不同的螢幕尺寸和器材

    配合 Flexbox 使用 :與 Flex 結合使用,可以實作更復雜的布局需求,靈活而強大

    使用場景

    復雜的布局需求 :適合需要精確控制多個專案在網格中位置和大小的復雜布局,如新聞網站的多欄布局或者儀表板的網格化布局

    網格化設計 :對於需要將頁面劃分為多個命名區域並對其進行管理的設計,如大型網頁或應用程式的板塊化設計

    響應式設計 :能夠根據不同的螢幕尺寸和器材自動調整布局,使得設計在流動通訊器材和桌面上都能夠優雅地呈現

    比如,嗶哩嗶哩推薦的影片列表就是用 grid 實作的, Grid 是一個非常強大的布局工具,特別適合於需要更高級和復雜布局需求的現代網頁設計和開發