網格佈局

CSS 網格佈局 是 Web 的一個二維佈局系統。它允許您將內容組織成行和列,並提供許多功能來簡化複雜佈局的建立。本文將解釋您入門網格佈局所需瞭解的所有內容。

先決條件 HTML 基礎知識(學習 HTML 簡介)以及 CSS 工作原理的概念(學習 CSS 簡介樣式化盒子)。
目標 瞭解網格佈局的基本概念以及如何使用 CSS 網格實現它。

什麼是網格佈局?

網格是水平和垂直線段的集合,它們建立一個模式,我們可以根據該模式排列我們的設計元素。它們幫助我們建立佈局,使我們的元素不會在頁面之間跳動或改變寬度,從而在我們的網站上提供更大的一致性。

網格通常有 **列**、**行**,以及每行和每列之間的間隙。這些間隙通常稱為 **槽**。

CSS grid with parts labelled as rows, columns and gutters. Rows are the horizontal segments of the grid and Columns are the vertical segments of the grid. The space between two rows is called as 'row gutter' and the space between 2 columns is called as 'column gutter'.

在 CSS 中建立網格

在確定了設計所需的網格後,您可以使用 CSS 網格佈局來建立它。我們首先了解網格佈局的基本功能,然後探討如何為您的專案建立一個簡單的網格系統。以下影片提供了使用 CSS 網格的清晰視覺解釋

定義網格

讓我們藉助示例嘗試網格佈局。下載並在您的文字編輯器和瀏覽器中開啟 起點檔案(您也可以 在這裡檢視)。您將看到一個示例,其中包含一個容器,該容器有一些子項。預設情況下,這些項以普通流顯示,導致它們一個接一個地顯示。在本課的初始部分,我們將使用此檔案來檢視其網格的行為。

與定義 Flexbox 的方式類似,您可以透過將 display 屬性的值設定為 grid 來定義網格佈局。與 Flexbox 一樣,display: grid 屬性將容器的所有直接子元素轉換為網格項。將以下 CSS 新增到您的檔案中

css
.container {
  display: grid;
}

與 Flexbox 不同,這些專案不會立即看起來有任何不同。宣告 display: grid 會為您提供一個單列網格,因此您的專案將繼續像在普通流中一樣一個接一個地顯示。

要檢視更像網格的內容,我們需要向網格中新增一些列。讓我們新增三列 200 畫素的列。您可以使用任何長度單位或百分比來建立這些列軌道。

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

將第二個宣告新增到您的 CSS 規則中,然後重新載入頁面。您應該會看到這些專案已重新排列,以便每個網格單元格中都包含一個專案。

使用 fr 單位建立靈活的網格

除了使用長度和百分比建立網格外,我們還可以使用 frfr 單位表示網格容器中可用空間的一部分,用於靈活地調整網格行和列的大小。

將您的軌道列表更改為以下定義,建立三個 1fr 軌道

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

您現在擁有了靈活的軌道。fr 單位按比例分配空間。您可以為您的軌道指定不同的正值,如下所示

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

第一個軌道獲得 2fr 的可用空間,其他兩個軌道獲得 1fr,使第一個軌道更大。您可以將 fr 單位與固定長度單位混合使用。在這種情況下,固定軌道的所需空間將首先使用,然後將剩餘空間分配給其他軌道。

**注意:**fr 單位分配的是 *可用* 空間,而不是 *所有* 空間。因此,如果您的軌道之一內部有較大的內容,則可共享的空閒空間會減少。

軌道之間的間隙

要建立軌道之間的間隙,我們使用以下屬性

css
.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 20px;
}

這些間隙可以是任何長度單位或百分比,但不能是 fr 單位。

注意: 用於設定間隙的 gap 屬性(column-gaprow-gapgap)以前需要新增 grid- 字首。規範已更改,但帶字首的版本將作為別名保留。為了安全起見並使程式碼更健壯,您可以同時新增這兩個屬性。

css
.container {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-gap: 20px;
  gap: 20px;
}

重複軌道列表

您可以使用 CSS 的 repeat() 函式重複整個或部分軌道列表。將您的軌道列表更改為以下內容:

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

現在您將獲得與之前相同的三個 1fr 軌道。傳遞給 repeat() 函式的第一個值指定您希望重複列表的次數,第二個值是軌道列表,可以是一個或多個您想要重複的軌道。

隱式和顯式網格

到目前為止,我們只指定了列軌道,但行會自動建立以容納內容。此概念突出了顯式網格和隱式網格之間的區別。以下是對這兩種網格型別之間差異的更多說明:

  • 顯式網格 使用 grid-template-columnsgrid-template-rows 建立。
  • 隱式網格 在內容放置在網格外部(例如放置在行中)時,透過繪製額外的網格線擴充套件定義的顯式網格。

預設情況下,在隱式網格中建立的軌道大小為 auto,這通常意味著它們足夠大以容納其內容。如果您希望為隱式網格軌道指定大小,可以使用 grid-auto-rowsgrid-auto-columns 屬性。如果您將 grid-auto-rows 的值設定為 100px,您會看到建立的行現在高 100 畫素。

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
  gap: 20px;
}

minmax() 函式

如果我們在這些軌道中新增的內容高度超過 100 畫素,那麼我們 100 畫素高的軌道將不會非常有用,在這種情況下會導致溢位。最好是讓軌道至少高 100 畫素,並且在新增更多內容時仍然可以擴充套件。關於網路的一個相當基本的事實是,您永遠無法真正知道某個東西的高度是多少——額外的內容或更大的字型大小會導致嘗試在每個維度上都完美畫素化的設計出現問題。

minmax() 函式允許我們為軌道設定最小和最大尺寸,例如 minmax(100px, auto)。最小尺寸為 100 畫素,但最大尺寸為 auto,它將擴充套件以容納更多內容。嘗試更改 grid-auto-rows 以使用 minmax 值。

css
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
  gap: 20px;
}

如果您新增額外的內容,您會看到軌道會擴充套件以使其適合。請注意,擴充套件是沿著行進行的。

儘可能多的列

我們可以結合我們學到的關於軌道列表、重複表示法和 minmax() 的一些知識來建立一個有用的模式。有時,能夠要求網格建立儘可能多地適合容器的列會很有幫助。我們透過使用 repeat() 函式設定 grid-template-columns 的值來做到這一點,但不是傳入數字,而是傳入關鍵字 auto-fit。對於函式的第二個引數,我們使用 minmax(),其最小值為我們希望具有的最小軌道大小,最大值為 1fr

現在在您的檔案中使用以下 CSS 嘗試一下:

css
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-auto-rows: minmax(100px, auto);
  gap: 20px;
}

這是因為網格正在建立儘可能多地適合容器的 200 畫素列,然後在所有列之間共享剩餘的空間。最大值為 1fr,正如我們已經知道的,它在軌道之間均勻分配空間。

基於行的佈局

現在,我們從建立網格轉向在網格上放置內容。我們的網格始終具有線條——這些線條從 1 開始編號,並與文件的 書寫模式 相關。例如,英語(從左到右書寫)中的第 1 列線將在網格的左側,第 1 行線在頂部,而在阿拉伯語(從右到左書寫)中,第 1 列線將在右側。

為了沿這些線定位專案,我們可以指定專案應放置的網格區域的起始線和結束線。我們可以使用四個屬性來執行此操作:

這些屬性接受行號作為其值,因此我們可以指定專案應從第 1 行開始,在第 3 行結束,例如。或者,您也可以使用簡寫屬性,讓您同時指定起始線和結束線,並用正斜槓 / 分隔。

  • grid-columngrid-column-startgrid-column-end 的簡寫。
  • grid-rowgrid-row-startgrid-row-end 的簡寫。

要檢視它的實際效果,請下載 基於線的放置起點檔案在此處檢視。它定義了一個網格和一個簡單的文章概述。您可以看到自動放置正在將每個專案放置到網格中的自己的單元格中。

讓我們透過使用網格線來安排我們網站的所有元素。將以下規則新增到 CSS 的底部:

css
header {
  grid-column: 1 / 3;
  grid-row: 1;
}

article {
  grid-column: 2;
  grid-row: 2;
}

aside {
  grid-column: 1;
  grid-row: 2;
}

footer {
  grid-column: 1 / 3;
  grid-row: 3;
}

注意: 您還可以使用值 -1 來定位結束列或行線,然後使用負值從末尾向內計數。另請注意,線條始終從顯式網格的邊緣開始計數,而不是從 隱式網格 開始計數。

使用 grid-template-areas 定位

在網格上排列專案的另一種方法是使用 grid-template-areas 屬性併為設計的各個元素命名。

刪除上一個示例中的基於線的定位(或重新下載檔案以獲得新的起點),然後新增以下 CSS。

css
.container {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer";
  grid-template-columns: 1fr 3fr;
  gap: 20px;
}

header {
  grid-area: header;
}

article {
  grid-area: content;
}

aside {
  grid-area: sidebar;
}

footer {
  grid-area: footer;
}

重新載入頁面,您將看到您的專案已像以前一樣放置,而無需使用任何行號!

grid-template-areas 的規則如下:

  • 您需要填充網格的每個單元格。
  • 要跨越兩個單元格,請重複名稱。
  • 要留空一個單元格,請使用 .(句點)。
  • 區域必須是矩形的——例如,您不能有一個 L 形區域。
  • 區域不能在不同位置重複。

您可以調整我們的佈局,將頁尾僅放置在文章下方,並將側邊欄跨越整個頁面。這是一種非常好的描述佈局的方式,因為僅從 CSS 中檢視就可以清楚地知道發生了什麼。

巢狀網格和子網格

可以在另一個網格內巢狀網格,從而建立 "子網格"。您可以透過在網格專案上設定 display: grid 屬性來實現。

讓我們擴充套件之前的示例,新增一個文章容器,並使用巢狀網格來控制多個文章的佈局。雖然我們在巢狀網格中僅使用一列,但我們可以使用 grid-template-rows 屬性將行劃分為 2:1:1 的比例。這種方法允許我們建立一種佈局,其中頁面頂部的文章具有較大的顯示,而其他文章則具有較小的、類似預覽的佈局。

css
.articles {
  display: grid;
  grid-template-rows: 2fr 1fr 1fr;
  gap: inherit;
}

article {
  padding: 10px;
  border: 2px solid rgb(79 185 227);
  border-radius: 5px;
}

為了更輕鬆地處理巢狀網格中的佈局,您可以在 grid-template-rowsgrid-template-columns 屬性上使用 subgrid。這使您可以利用父網格中定義的軌道。

在以下示例中,我們使用的是 基於線的放置,使巢狀網格能夠跨越父網格的多列和多行。我們添加了 subgrid 以繼承父網格的列軌道,同時為巢狀網格中的行新增不同的佈局。

html
<div class="container">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div id="subgrid">
    <div>Five</div>
    <div>Six</div>
    <div>Seven</div>
    <div>Eight</div>
  </div>
  <div>Nine</div>
  <div>Ten</div>
</div>
css
.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(1, 1fr);
  gap: 10px;
}

#subgrid {
  grid-column: 1 / 4;
  grid-row: 2 / 4;
  display: grid;
  gap: inherit;
  grid-template-columns: subgrid;
  grid-template-rows: 2fr 1fr;
}

網格框架

有許多網格框架可用,提供 12 列或 16 列網格,以幫助您佈置內容。好訊息是,您可能不需要任何第三方框架來幫助您建立基於網格的佈局——網格功能已包含在規範中,並且大多數現代瀏覽器都支援它。

下載起點檔案。它包含一個定義了 12 列網格的容器以及我們在前兩個示例中使用的相同標記。現在,我們可以使用基於線的放置將我們的內容放置在 12 列網格上。

css
header {
  grid-column: 1 / 13;
  grid-row: 1;
}

article {
  grid-column: 4 / 13;
  grid-row: 2;
}

aside {
  grid-column: 1 / 4;
  grid-row: 2;
}

footer {
  grid-column: 1 / 13;
  grid-row: 3;
}

如果您使用 Firefox 網格檢查器 將網格線疊加在您的設計上,您可以看到我們的 12 列網格是如何工作的。

A 12 column grid overlaid on our design.

測試你的技能!

您已閱讀完本文,但您還記得最重要的資訊嗎?在繼續之前,您可以找到一些進一步的測試來驗證您是否保留了這些資訊——請參閱 測試您的技能:網格

總結

在本概述中,我們介紹了 CSS 網格佈局的主要功能。您應該能夠在您的設計中開始使用它。要進一步深入瞭解規範,請閱讀我們關於網格佈局的指南,這些指南可在下面找到。

另請參閱