帶有 CSS 網格和命名列的編輯設計模式
已發表: 2022-03-10許多網站,尤其是那些顯示長篇內容的網站,都有相當簡單的重複組件模式:圖像的全角區域、中心內容區域,也許還有兩個半角塊的拆分視圖。 這些組件重複顯示文章、圖像和其他相關內容——內容編輯在創建文章以供發佈時選擇正確的組件。
在本文中,我將展示這種編輯設計的方法,它建立在一些技術的基礎上,其中一些將在以下文章中討論:
- “用 CSS 網格佈局突圍”
- “用 CSS Grid 突圍解釋”
- “在 CSS 網格佈局中命名事物”
除了這是一種命名佈局部分的好方法之外,這種技術還公開了一大堆關於網格佈局的有趣內容,您可能會發現它們在創建自己的佈局模式時很有用。 它還展示了 subgrid 的更多承諾(即將到來的第 2 級網格規範的一部分,並在 Firefox 中實現)。
在 CSS 網格佈局中命名事物
使用 CSS 網格佈局時,您可以命名線條和區域。 這兩件事都可以使使用網格——尤其是複雜的網格——更加直接。 與團隊合作時,為佈局中的事物定義命名約定可能很有用; 與從column-line: 3 / 9
放置的東西相比,使用grid-area: content
放置的東西最終會更容易理解。
使用grid-template-areas
方法時,您可以使用grid-area
屬性為要放置在網格上的項目命名,然後將它們放置在網格周圍。 在以下示例中,帶有grid-area: content
的項目進入由grid-template-areas
屬性定義的網格區域:
這適用於您將一件物品放入一個區域的組件。 但是,如果您想將多個東西放入內容區域(一個在另一個之下),則使用grid-area
是錯誤的方法。 相反,您可以為列行定義名稱並將項目從開始行放置到結束行。
然而,當使用網格區域方法時,當使用grid-column
或grid-row
放置項目時,我們必須知道開始線和結束線,這不是那麼整潔 - 或者我們嗎?
看看下一個 CodePen 示例。 我的項目通過使用grid-column
屬性使用單個名稱或標識放置,即使某些目標網格區域跨越多個列:
我的目標是在實際使用網格時抽像出網格設置的複雜性。 我可以投入大量工作來創建初始網格,然後在填充頁面時無需過多考慮就可以放置東西。 我還想確保我們可以在構建文章時盡可能頻繁地重複這些組件。 我想到的是使用 CMS 的內容創建者,並使用不同的模式創建內容塊,同時知道它們將在整個網格上正確地放置在另一個之下。
為了理解我是如何走到這一步的,需要了解一些關於 CSS 網格佈局以及命名線和區域的知識。
我們可以命名線路
正如您在上面的第二個示例中已經看到的那樣,我們可以在網格上命名幾乎任何我們喜歡的線條——除了單詞span
。 該名稱是一個標識而不是一個字符串,這就是它不被引用的原因。
但是,您將看到許多使用命名約定name-start
和name-end
的示例,它們將-start
附加到起始行的名稱上,將-end
附加到結束行的名稱上。 這不是純粹的約定,對於我將向您展示的技術,為什麼我們需要以這種方式命名我們的行。 因此,您應該為所描述的區域選擇一個名稱,然後添加-start
和-end
後綴——當然,它們需要匹配!
我們在方括號內命名我們的行。 行可以(並且經常需要)有多個名稱。 在這種情況下,空格分隔名稱。 使用基於線的定位放置項目時,您可以為線選擇任何名稱來進行放置。
有了我們的命名行,我們可以通過指定開始和結束行名稱來使用grid-column
放置我們的項目。 此模式與使用行號相同,因此斜線之前的名稱是起始行,斜線之後的名稱是結束行。
這放置了項目,但不是我在示例中使用的每個項目的整潔單一名稱。 但是,由於 Grid 處理命名區域和線的特殊方式,我們現在已經準備就緒。
線路名稱給我們一個命名區域
假設你像我一樣用-start
和-end
命名你的行,Grid 會給你一個你使用的主要名稱的命名區域。 因此,就我而言,我有名為content
、 start-half
、 end-half
、 full
和center
的區域。 這些區域中的每一個都是單行(因為我沒有命名行),但是,它將跨越從-start
到-end
行的列軌道。
命名區域為我們提供了使用的主要名稱的命名行
如果我們希望能夠像有列名一樣放置我們的項目,我們還需要利用這樣一個事實,即在創建網格區域時,我們會獲得所使用的主要名稱的行名; 也就是說,主名稱是刪除了-start
和-end
的名稱。 此行名稱解析為區域的開始或結束,具體取決於我們的目標是grid-column-start
還是grid-column-end
。
因此,我們有一個名為content
的區域,因為我們有名為content-start
和content-end
的列行。 名為content
的區域還使我們能夠使用grid-column-start: content
將解析到該內容區域的起始行,而grid-column-end: content
將解析到內容區域的結束行。
因此,這意味著我們可以使用以下命令將項目放入內容區域:
.content { grid-column: content / content; }
接下來,我們現在可以進一步整理這項技術,因為如果您使用命名行作為grid-column-start
並省略結束行(而不是像使用行號那樣跨越一個軌道),網格將名稱複製到結束行。 因此, grid-column: content
與grid-column: content / content;
這就是我們需要能夠使用具有簡單單一名稱的grid-column
放置項目的全部內容。 這種行為完全符合規定,而不是某種“黑客”。 它展示了創建 Grid Layout 規範的深度思考,以及為使我們的設計中的項目佈局變得如此簡單而投入的大量細緻工作。
使用 Subgrid 賦予該技術超能力
我認為這種技術是一種很好的技術,它能夠以一種非常直接的方式來聲明元素應該放置在網格上的什麼位置。 但是,如果我們在混合中添加子網格支持,它確實會變得非常強大。
目前,subgrid 正在 Firefox 中實現,因此接下來的這些示例需要 Firefox Nightly 才能運行。 你可以在這裡下載 Nightly。
grid-template-columns
和grid-template-rows
的subgrid
值意味著在父網格上創建的大小可以由作為網格子項的項目(假設它也使用網格佈局)通過display: grid
應用display: grid
。
注意:您可以在 Smashing Magazine “CSS Grid Level 2: Here Comes Subgrid” 和 “Digging In the Display Property: Grids All Way Down” 上的文章中閱讀更多關於 subgrid 功能的信息。
父項中的線名被傳遞到子網格中
除了將軌道尺寸信息傳遞到子網格之外,在父網格上設置的任何線名都將被傳遞。這意味著我們可以在子網格組件中使用我們的“列名”,使得這個解決方案在一個世界中非常有用子網格存在。 放置在content
中的項目——即使嵌套在子網格內——將與作為主網格的直接子級放置的項目對齊。
在下一個示例中,我將兩個元素直接嵌套在 div 中,類為full-2
。 我還在.content
中放置了一個ul
。 如果我們查看full-2
中的項目,為了將它們放置在父網格上,我們需要使選擇器full-2
成為具有display: grid
的網格,然後使用值為subgrid
的grid-template-columns
屬性.
這會導致.full-2
上的網格使用父網格上定義的軌道,並可以訪問那裡定義的命名線。 由於這是一個全寬項目,因此在放置我們的項目方面,它的行為實際上就像父網格一樣。 然後,我們可以使用為不同列定義的任何名稱來放置項目。 在這種情況下,我將兩個子元素都設置為grid-column: center
並且它們在該中心區域中一個接一個地顯示。
.full-2 { grid-row: 4; grid-column: full; display: grid; row-gap: 10px; grid-template-columns: subgrid; } .full-2 > div { background-color: rgb(124,222,220); grid-column: center; }
如果我們看一下嵌套在.content
中的ul
,我們需要在選擇器.content
上創建一個子網格,就像上一個示例一樣; 當我們這樣做時, ul
落入子網格的第一個軌道。 如果我們想在 subgrid 上佈置監聽項,我們需要做兩件事:通過放置 ul 與它的 parent 佔用相同的區域grid-column: content
,然後使其成為一個網格,即一個子網格。
完成此操作後,列表項將使用自動放置到子網格的列軌道中進行佈局:
.content { grid-row: 1; grid-column: content; display: grid; grid-template-columns: subgrid; } .content ul { grid-column: content; display: grid; row-gap: 10px; grid-template-columns: subgrid; }
一旦你有了你的網格,你就可以像以前一樣使用父級的名稱。
.content li:nth-child(1) { grid-column: center; } .content li:nth-child(2) { grid-column: start-half; } .content li:nth-child(3) { grid-column: end-half; } .content li:nth-child(4) { grid-column: content; }
如果你有 Firefox Nightly,你可以在這個 CodePen 示例中看到完整的演示:
您可以像這樣將“嵌套”子網格保留到您的標記結構中,並且每次都會傳遞行名稱。 這是一個我認為會特別有用的功能。
創建子網格時,行號對應於子網格的線,而不是父網格。 因此,如果您確實想確保子網格中的元素與父網格對齊,那麼使用線名或命名區域(如本例所示)將使這變得簡單而合乎邏輯。
包起來
您現在知道如何將這種技術用於您的主網格,並且希望用不了多久我們就會開始在所有瀏覽器中看到對子網格的支持。 它將啟用諸如此類的技術,並使其非常強大,供我們使用。