理解 CSS 網格:網格線

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

在本系列的第一篇文章中,我了解瞭如何創建網格容器以及應用於構成網格的父元素的各種屬性。 一旦你有了一個網格,你就有了一組網格線。 在本文中,您將學習如何通過向網格容器的直接子項添加屬性來將項目放置在這些行上。

我們將涵蓋:

  1. 放置屬性grid-column-startgrid-column-endgrid-row-startgrid-row-end及其簡寫grid-columngrid-row
  2. 如何使用grid-area按行號放置。
  3. 如何根據行名放置項目。
  4. 放置項目時隱式和顯式網格之間的區別。
  5. 使用span關鍵字,帶有一點額外的subgrid
  6. 混合自動放置和放置的物品時要注意什麼。
  • 第 1 部分:創建網格容器
  • 第 2 部分:網格線
  • 第 3 部分:網格模板區域

基於線定位的基本概念

要將項目放置在網格上,我們設置它開始的行,然後是我們希望它結束的行。 因此,對於五列五行網格,如果我希望我的項目跨越第二和第三列軌道,以及第一、第二和第三行軌道,我將使用以下 CSS。 請記住,我們的目標是線路,而不是軌道本身。

 .item { grid-column-start: 2; grid-column-end: 4; grid-row-start: 1; grid-row-end: 4; }

這也可以指定為簡寫,正斜杠之前的值是開始行,m 之後的值是結束行。

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

在 CodePen 上,您可以看到示例,並更改項目跨越的行。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines:放置速記。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines:放置速記。

請注意,我們的盒子背景拉伸整個區域的原因是因為對齊屬性align-selfjustify-self的初始值是拉伸的。

如果您只需要您的項目跨越一個軌道,那麼您可以省略結束行,因為默認行為是項目跨越一個軌道。 我們在上一篇文章中自動放置項目時看到了這一點,每個項目進入一個單元格 - 跨越一列和一行軌道。 因此,要使項目從第 2 行跨越到第 3 行,您可以編寫:

 .item { grid-column: 2 / 3; }

錯過終點線也是完全正確的:

 .item { grid-column: 2; }

grid-area速記

您還可以使用grid-area放置項目。 我們將在以後的文章中再次遇到此屬性,但是,當與行號一起使用時,它可以用於設置所有四行。

 .item { grid-area: 1 / 2 / 4 / 4; }

這些行號的順序是grid-row-startgrid-column-startgrid-row-endgrid-column-end 。 如果使用橫向語言,從左到右書寫(如英語),那就是上、左、下、右。 您可能已經意識到這與我們通常在 CSS 中指定諸如邊距之類的速記方式相反——它們依次為上、右、下、左。

這樣做的原因是,無論您使用哪種書寫模式或方向,網格都以相同的方式工作,我們將在下面詳細介紹這一點。 因此,設置兩個開始然後結束比將值映射到屏幕的物理尺寸更有意義。 我不傾向於將此屬性用於基於行的放置,因為我認為grid-columngrid-row的二值簡寫在掃描樣式表時更具可讀性。

跳躍後更多! 繼續往下看↓

顯式網格上的線

我在上一篇文章中提到了顯式與隱式網格。 顯式網格是您使用grid-template-columnsgrid-template-rows屬性創建的網格。 通過定義列和行軌道,您還可以在這些軌道之間以及網格的開始和結束邊緣定義線。

這些行已編號。 編號從塊和內聯方向的起始邊緣的 1 開始。 如果您處於水平書寫模式,句子從左側開始並向右運行,這意味著塊方向的第 1 行位於網格的頂部,而行內方向的第 1 行是左側線。

項目顯示在 Firefox Grid Inspector 突出顯示行的位置
放置在網格上的項目

如果您使用水平 RTL 語言工作 - 就像使用阿拉伯語工作一樣 - 塊方向的第 1 行仍位於頂部,但內聯方向的第 1 行位於右側。

該項目現在從網格的右側放置
與方向相同的位置:rtl

如果您在垂直書寫模式下工作,並且在下圖中我設置了writing-mode: vertical-rl ,那麼在該書寫模式下,第 1 行將位於塊方向的開頭,在這種情況下位於右側。 內聯方向的第 1 行位於頂部。

整個網格現在旋轉了 90 度
書寫模式下的相同位置:vertical-rl

因此,網格線與文檔或組件的書寫模式和腳本方向相關聯。

顯式網格的最後一行是數字-1並且行從該點開始倒數,使第-2行成為倒數第二行。 這意味著,如果您想跨越顯式網格的所有軌道上的項目,您可以這樣做:

 .item { grid-column: 1 / -1; }

隱式網格上的線

如果您創建了隱式網格軌跡,那麼它們也從 1 開始計數。在下面的示例中,我為列創建了一個顯式網格,但是,行軌跡已經在隱式網格中創建,我使用的是grid-auto-rows將這些大小調整為 5em。

具有placed類的項目已放置為從第 1 行到第 -1 行。 如果我們為兩行使用顯式網格,則該項目應跨越兩行。 因為行軌跡是在隱式網格中創建的,所以第-1行解析為第 2 行,而不是第 3 行。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines: explicit vs. implicit grids。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines: explicit vs. implicit grids。

目前沒有辦法定位隱式網格的最後一行,不知道你有多少行。

根據命名行放置項目

在上一篇文章中,我解釋了除了行號之外,您還可以選擇命名網格上的行。 您可以通過在軌道大小之間的方括號內添加一個或多個名稱來命名這些行。

 .grid { display: grid; grid-template-columns: [full-start] 1fr [main-start] 2fr 2fr [main-end full-end]; }

一旦你有一些命名的行,你可以在放置你的項目時將行號換成一個名稱。

 .item { grid-column: main-start / main-end; } 

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:命名線。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:命名線。

如果您的行有多個名稱,您可以在放置項目時選擇您喜歡的任何一個,所有名稱都將解析為同一行。

注意命名行時會發生一些有趣的事情。 查看我的文章“在 CSS 網格佈局中命名事物”了解更多信息。

如果有多個同名的行會發生什麼?

如果您有多個具有相同名稱的行,您會得到一些有趣的行為。 如果您在repeat()表示法中命名行,就會發生這種情況。 在下面的示例中,我有一個 8 列網格,通過重複 4 次1fr 2fr模式創建。 我在較小的軌道sm和較大的軌道lg之前命名了這條線。 這意味著我有 4 行每個名稱。

在這種情況下,我們可以使用名稱作為索引。 因此,要放置一個從名為sm的第二行開始並延伸到名為lg的第三行的項目,我使用grid-column: sm 2 / lg 3 。 如果您使用不帶數字的名稱,則該名稱將始終解析為具有該名稱的第一行。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:命名線。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:命名線。

使用span關鍵字

在某些情況下,您知道您希望一個項目跨越一定數量的軌道,但是您不知道它在網格上的確切位置。 例如,您使用自動放置來放置項目,但希望它們跨越多個軌道而不是默認的 1。在這種情況下,您可以使用span關鍵字。 在下面的示例中,我的項目從auto行開始,這是自動放置放置它的行,然後它跨越 3 個軌道。

 .item { grid-column: auto / span 3; } 

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: span 關鍵字。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: span 關鍵字。

一旦我們廣泛支持grid-template-columnsgrid-template-rowssubgrid值,這種技術將變得非常有用。 例如,在卡片具有標題和要相互對齊的主要內容區域的卡片佈局中,您可以使每張卡片跨越 2 行,同時仍然允許通常的自動放置行為。 各個卡片將使用subgrid作為它們的行(即每行有兩行)。 如果您使用 Firefox,您可以在下面的示例中看到這一點,並閱讀我的文章 CSS Grid Level 2: Here Comes Subgrid 以了解有關 subgrid 的更多信息。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: span 關鍵字和 subgrid。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: span 關鍵字和 subgrid。

/

帶有 Firefox Grid Inspector 的卡片網格,顯示它們分別位於網格的兩行上
Firefox 中使用 Grid Inspector 的示例

使用基於行的放置對項目進行分層

網格將自動將項目放置到網格上的空單元格中,它不會將項目堆疊到同一個單元格中。 但是,通過使用基於行的放置,您可以將項目放入同一個網格單元中。 在下一個示例中,我有一個跨越兩行軌道的圖像,以及放置在第二個軌道中並具有半透明背景的標題。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:帶有分層元素的卡片。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:帶有分層元素的卡片。

項目將按照它們在文檔源中出現的順序堆疊。 所以在上面的例子中,標題出現在圖像之後,因此顯示在圖像的頂部。 如果標題先出現,那麼它最終會顯示在圖像後面,我們將無法看到它。 您可以使用z-index屬性控制此堆疊。 如果標題在源中排在第一位很重要,那麼您可以使用z-index ,標題的值高於圖像。 這將強制標題顯示在圖像頂部,以便可以閱讀。

混合基於行和自動放置

如果您將放置的物品與自動放置的物品混合在一起,則需要格外小心。 當項目完全自動放置在網格中時,它們將按順序將自己放置到網格上,每個都找到下一個可用的空白空間來放置自己。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: auto-placement。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: auto-placement。

默認行為總是向前推進,如果項目不適合網格,則留下一個間隙。 您可以通過使用值為dense的屬性grid-auto-flow來控制此行為。 在這種情況下,如果有一個項目適合網格中已經留下的空白,它將按照源順序放置以填補空白。 在下面使用密集包裝的示例中,項目 3 現在放置在項目 2 之前。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: auto-placement and dense packing。

請參閱 CodePen 上 Rachel Andrew (@rachelandrew) 的 Pen Grid Lines: auto-placement and dense packing。

請注意,此行為可能會導致在文檔中切換的用戶出現問題,因為視覺佈局將與他們遵循的源順序不同步。

如果您已經放置了一些物品,自動放置的工作方式會略有不同。 放置的物品將首先被定位,然後自動放置將尋找第一個可用的間隙以開始放置物品。 如果您通過空網格行在佈局頂部留下了一些空白,然後引入一些自動放置的項目,它們將最終出現在該軌道中。

為了在最後一個示例中進行演示,我放置了基於行的定位屬性,項目 1 和 2 將第一行留空。 後來的項目已經向上移動以填補空白。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:自動放置與放置的項目混合。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Grid Lines:自動放置與放置的項目混合。

這種行為值得理解,因為如果您在佈局中引入一些尚未在網格上放置的新元素,這可能意味著項目最終會出現在奇怪的位置。

包起來

這幾乎就是您需要了解的有關網格線的所有信息。 請記住,您總是有編號的行,無論您如何使用網格,您始終可以將項目從一個行號放置到另一個行號。 我們將在以後的文章中介紹的其他方法是指定佈局的替代方法,但基於由編號線創建的網格。

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