了解 CSS 網格:網格模板區域

已發表: 2022-03-10
快速總結 ↬在一個新系列中,Rachel Andrew 分解了 CSS 網格佈局規範。 這次,我們來看看如何使用grid-template-areas來放置項目。

使用 CSS 網格佈局時,您始終可以將項目從一條網格線放置到另一條網格線。 但是,還有另一種描述佈局的方式,一種本質上是可視化的方式。 在本文中,我們將學習如何使用grid-template-areas屬性來定義網格上的位置,並了解該屬性是如何工作的。

如果您錯過了本系列之前的文章,您可以在這裡找到它們:

  • 第 1 部分:創建網格容器
  • 第 2 部分:網格線
  • 第 3 部分:網格模板區域

grid-template-areas描述佈局

grid-template-areas屬性接受一個或多個字符串作為值。 每個字符串(用引號括起來)代表網格的一行。 您可以在使用grid-template-rowsgrid-template-columns定義的網格上使用該屬性,或者您可以創建佈局,在這種情況下,所有行都將自動調整大小。

以下屬性和值描述了一個具有四個區域的網格——每個區域跨越兩個列軌道和兩個行軌道。 通過在您希望它覆蓋的所有單元格中重複名稱,使一個區域跨越多個軌道:

 grid-template-areas: "one one two two" "one one two two" "three three four four" "three three four four";

通過使用grid-area屬性使用 ident 命名,將項目放置到佈局中。 因此,如果我想將一個帶有test類的元素放入名為one的網格區域中,我使用以下 CSS:

 .test { grid-area: one; }

您可以在下面顯示的 CodePen 示例中看到這一點。 我有四個項目(一到四級); 這些使用grid-area屬性分配給相關的網格區域,因此在正確的框中顯示在網格上。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Simple grid-template-areas 示例。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Simple grid-template-areas 示例。

如果您使用 Firefox Grid Inspector,那麼您可以看到區域名稱和網格線,表明每個項目確實跨越了兩行和兩列軌道——所有這些都沒有對項目本身進行任何基於行的定位。

四個項目的網格,Firefox Grid Inspector 突出顯示行
每個項目跨越兩行和兩列

使用grid-template-areas規則

以這種方式創建佈局時有一些規則。 違反規則將使值無效,因此您的佈局不會發生。 第一條規則是您必須描述一個完整的網格,即必須填充網格上的每個單元格。

如果您確實想將一個單元格(或多個單元格)留作空白,您可以通過插入. 或系列,例如... ,它們之間沒有空格。

因此,如果我將grid-template-areas的值更改如下:

 grid-template-areas: "one one two two" "one one two two" ". . four four" "three three four four";

我現在有兩個沒有內容的單元格。 第三項僅顯示在網格的最後一行。

一個項目現在只跨越一行,Firefox Grid Inspector 突出顯示這些行
現在網格中有空格

您只能定義每個區域一次,這意味著您不能使用此屬性將內容複製到網格上的兩個位置! 因此,以下值將無效並導致整個屬性被忽略,因為我們複製了區域three

 grid-template-areas: "one one three three" "one one two two" "three three four four" "three three four four";

您不能創建非矩形區域,因此該屬性不能用於創建“L”或“T”形區域 - 使以下值也無效:

 grid-template-areas: "one one two two" "one one one one" "three three four four" "three three four four";

格式化字符串

我喜歡像上面那樣顯示grid-template-areas的值(每個字符串代表前一行下方的一行)。 這給了我一個佈局的直觀表示。

為了解決這個問題,在每個單元格之間添加額外的空白字符以及使用多個. 表示空單元格的字符。

在下面的值中,我在較小的單詞之間使用了多個空白字符,並且還使用了多個. 字符,所以空單元格排列:

 grid-template-areas: "one one two two" "one one two two" "..... ..... four four" "three three four four";

也就是說,將所有字符串放在一行中也是完全有效的,因此我們可以將示例編寫如下:

 grid-template-areas: "one one two two" "one one two two" "three three four four" "three three four four";
跳躍後更多! 繼續往下看↓

解釋grid-template-areasgrid-area

每個區域都需要是一個完整的矩形的原因是它需要與您可以使用基於線的放置創建的形狀相同。 如果我們堅持上面的示例,我們可以像在下一個 CodePen 中那樣使用網格線進行佈局。 在這裡,我像以前一樣創建了我的網格。 然而,這一次,我使用網格線來創建定位,使用了常用的grid-column-startgrid-column-endgrid-row-startgrid-row-end屬性。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的鋼筆網格線放置。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的鋼筆網格線放置。

注意如果您閱讀我之前的文章“理解 CSS 網格:網格線”,您就會知道可以使用grid-area作為同時聲明所有四行的簡寫。

這意味著我們還可以使用以下行順序創建佈局:

  • grid-row-start
  • grid-column-start
  • grid-row-end
  • grid-column-end
 .one { grid-area: 1 / 1 / 3 / 3; } .two { grid-area: 1 / 3 / 3 / 5; } .three { grid-area: 3 / 1 / 5 / 3; } .four { grid-area: 3 / 3 / 5 / 5; }

grid-area屬性很有趣,因為它可以獲取行號和行名。 了解它在每種模式下的不同行為方式也很重要。

使用帶有行號grid-area

如果您將grid-area屬性與行號一起使用,則將按上述順序分配行。

如果您遺漏了任何值——因此提供 1、2 或 3 個行號——缺失值將設置為auto ,這意味著該區域將跨越 1 個軌道(這是默認值)。 因此,下面的 CSS 將放置一個項目grid-row-start: 3並將所有其他值設置為 auto,因此,該項目將自動放置在第一個可用的列軌道中,並跨越一個行軌道和一個列軌道。

 grid-area: 3;

使用帶有標識grid-area

如果您使用 ident(在網格佈局中稱為命名區域),則grid-area屬性也需要四行。 如果您已按照“理解 CSS 網格:創建網格容器”中所述在網格上命名線,那麼您可以像使用編號線一樣使用這些命名線。

但是,當您錯過某些行時會發生什麼與您使用標識而不是數字時發生的情況不同。

下面,我創建了一個帶有命名線的網格,並使用grid-area來放置一個項目(缺少最終值):

 .grid { display: grid; grid-template-columns: [one-start three-start] 1fr 1fr [one-end three-end two-start four-start] 1fr 1fr [two-end four-end]; grid-template-rows: [one-start two-start] 100px 100px [one-end two-end three-start four-start] 100px 100px [three-end four-end];; } .two { grid-area: two-start / two-start / two-end; }

這意味著我們缺少grid-column-end的行名。 規範說在這種情況下, grid-column-end應該使用grid-column-start的副本。 如果grid-column-endgrid-column-start相同,則結束線被丟棄,本質上該值設置為 auto,因此我們像編號版本一樣跨越一個軌道。

如果我們錯過了第三個值grid-row-end ,也會發生同樣的事情; 它與grid-row-start相同,因此變為auto

查看下一個 CodePen 示例,了解如何使用每個grid-area以及如何更改項目的佈局:

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的網格區域中的 Pen Missing idents。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的網格區域中的 Pen Missing idents。

這就解釋了為什麼grid-area使用代表區域名稱的單個值 ident 工作。

當我們使用grid-template-areas屬性創建命名區域時,每個區域的邊緣都可以通過與您使用的區域名稱相同的線名來引用。 在我們的例子中,我們可以將我們的區域命名為one並使用命名行放置我們的項目,如下所示:

 .one { grid-row-start: one; grid-row-end: one; grid-column-start: one; grid-row-end: one; }

如果該行是-start行, one解析為列或行的開始端。 如果它是-end行, one解析為列或行的結束行。

這意味著當我們說grid-area: one時,我們省略了grid-area簡寫的最後三個值; 它們最終都是第一個值的副本——在我們的例子中,它們都變成one ,並且項目的放置方式與我們的普通用法一樣。

網格佈局中的命名方式很聰明,並且可以實現一些有趣的事情,我在之前的文章“CSS 網格佈局中的命名”和“使用 CSS 網格和命名列的編輯設計模式”中已經寫過這些內容。

使用grid-template-areas時對項目進行分層

使用grid-template-areas時,每個單元格只能有一個名稱,但是,您仍然可以在以這種方式完成主佈局後向網格添加其他項目。 您可以像往常一樣使用行號。

在下面的 CodePen 示例中,我添加了一個附加項目,並使用基於行的定位將其定位在已定位的項目上:

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Placeing an item with line numbers。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Placeing an item with line numbers。

您還可以使用在創建常用列或行時定義的行名稱。 更好的是,您將擁有一些由區域形成創建的線名。 我們已經看到瞭如何獲得帶有區域名稱的四個行名稱。 您還可以在每個區域的起始邊緣獲得一條線,並在區域名稱後附加-start ,在每個區域的結束邊緣添加一條線,並附加-end

因此,名為one的區域具有名為one-start起始邊緣線和名為one-end結束邊緣線。

然後,您可以使用這些隱式行名稱將項目放置在網格上。 如果您在不同的斷點處重新定義網格,只要您始終希望放置的項目位於某個行名之後,這將很有用。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Placeing an item with implicit line names。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Placeing an item with implicit line names。

在響應式設計中使用網格模板區域

我經常在組件庫中構建組件,我發現使用grid-template-areas有助於從 CSS 中準確查看組件的外觀。 除了更改可用列軌道的數量之外,有時還可以通過重新定義grid-template-areas的值在不同的斷點重新定義組件也非常簡單。

在下面的 CSS 中,我為我的組件定義了一個單列佈局。 接下來,在最小寬度為 600 像素的情況下,我重新定義了列數以及grid-template-areas的值,以創建具有兩列的佈局。 這種方法的好處是,任何查看此 CSS 的人都可以看到佈局是如何工作的!

 .wrapper { background-color: #fff; padding: 1em; display: grid; gap: 20px; grid-template-areas: "hd" "bd" "sd" "ft"; } @media (min-width: 600px) { .wrapper { grid-template-columns: 3fr 1fr; grid-template-areas: "hd hd" "bd sd" "ft ft"; } } header { grid-area: hd; } article {grid-area: bd; } aside { grid-area: sd; } footer { grid-area: ft; }

可訪問性

使用此方法時需要注意,很容易移動東西並導致視覺顯示與底層源訂單斷開連接的問題。 任何在網站上瀏覽的人,或者在說出內容的同時觀看屏幕的人,都將使用源中的順序。 通過從該順序移動顯示,您可以創建一個非常混亂、斷開連接的體驗。 不要使用這種方法來移動東西而不確保源的順序合理並匹配視覺體驗。

概括

這就是使用grid-template-areagrid-area屬性來創建佈局的內幕。 如果您之前沒有使用過這種佈局方法,請嘗試一下。 我發現這是一種嘗試佈局的好方法,並且在設計佈局原型時經常使用它——即使出於某種原因,我們最終將在生產版本中使用不同的方法。

CSS 中的溢出和數據丟失

CSS 旨在使您的內容保持可讀性。 讓我們探討一下您可能會在網頁設計中遇到溢出的情況,以及 CSS 如何演變為創建更好的方法來管理和設計未知數量的內容。 閱讀相關文章 →