發布日期:2024 年 9 月 19 日,上次更新日期:2026 年 2 月 13 日
CSS 工作群組已將這兩項 CSS 砌體提案合併為一份規格草案。該團體希望藉此讓兩者更容易比較,並做出最終決定。Chrome 團隊仍認為,獨立的砌磚語法是最佳做法。雖然先前的文章中提及的最大效能問題已解決,但語法、初始值,以及結合格線的版本是否容易學習,仍令人擔憂。
不過,為了測試我們的假設,我們已完成一些範例,說明每種版本的格狀配置如何運作。請參考本文中的範例,並提供意見回饋,協助我們做出決定,然後繼續開發這項功能。
這篇文章並未涵蓋所有可能的用途,但很明顯,將 Masonry 從格線版面配置中分離出來,不會導致功能缺損。事實上,情況可能正好相反。如本文所述,display: masonry 版本創造了新商機,語法也更簡單。此外,許多開發人員也擔心,使用格狀配置重新排序項目可能會導致無障礙問題。我們也透過建議的 reading-flow 屬性,解決這兩種語法版本的問題。
基本砌體版面配置
說到磚塊排列,大多數人想到的就是這種版面配置。項目會顯示在資料列中,放置第一個資料列後,後續項目會移至較短項目留下的空間。
前往 display: masonry
如要建立格狀布局,請將 display 屬性的值設為 masonry。這會建立一個磚塊式版面配置,其中包含您定義的欄軌 (或由內容定義),以及其他軸中的磚塊。第一個項目會顯示在區塊和內嵌的開頭 (因此在英文中為左上角),項目則會以內嵌方向排列。
如要定義軌道,請使用 masonry-template-tracks,並將軌道清單值做為 CSS 格線版面配置使用。
.masonry {
display: masonry;
masonry-template-tracks: repeat(3, 1fr);
gap: 10px;
}
前往 display: grid
如要建立格狀版面配置,請先使用 display 屬性的 grid 值建立格線版面配置。使用 grid-template-columns 屬性定義資料欄,然後為 grid-template-rows 指定 masonry 值。
這會建立版面配置,並自動放置格線項目,但每列中的項目會使用砌磚版面配置,並重新排列,以佔用前一列中較小項目留下的空間。
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: masonry;
gap: 10px;
}
這兩種做法的考量點
這兩種方法之間的主要差異在於,即使您未指定任何具有 masonry-template-tracks 的軌道,display: masonry 版本仍會提供砌塊格線配置。因此您可能只需要 display: masonry。這是因為 masonry-template-tracks 的初始值為 repeat(auto-areas, auto)。版面配置會建立盡可能多的自動調整大小軌,以配合容器。
砌體反向流動
這項規格包含變更磚塊流方向的方法。舉例來說,您可以變更流程,從區塊結尾向上顯示。
前往 display: masonry
使用 display: masonry 建立格狀版面配置,然後使用 masonry-direction 並將值設為 column-reverse。
.masonry {
display: masonry;
masonry-template-tracks: repeat(3, 1fr);
masonry-direction: column-reverse;
}
前往 display: grid
使用 display: grid 和 grid-template-rows: masonry 建立砌磚版面配置。
接著,使用 grid-auto-flow 屬性並將值設為 row-reverse,讓項目從格線容器的區塊結尾開始版面配置。
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: masonry;
grid-auto-flow: row-reverse;
}
這兩種做法的考量點
display: masonry 版本與彈性方塊的運作方式非常相似。使用 masonry-direction 屬性,並將值設為 column-reverse,即可變更資料欄的流動方向。
CSS 格線版本使用 grid-auto-flow。以目前定義來說,grid-auto-flow: row-reverse 和 grid-auto-flow: column-reverse 的效果相同。這可能會造成混淆,因為您可能會預期這些項目會執行不同的動作。
資料列的磚塊
您也可以變更方向來定義資料列。
前往 display: masonry
使用 display: masonry 建立格狀配置,然後將 masonry-direction 的值設為 row。除非您希望資料列具有特定區塊大小,否則不需要指定任何軌道大小,因為預設值為 auto,因此軌道會根據所含內容調整大小。
.masonry {
display: masonry;
masonry-direction: row;
}
前往 display: grid
.masonry {
display: grid;
grid-template-columns: masonry;
grid-template-rows: repeat(3, 1fr);
}
這兩種做法的考量點
與反向流程相同,將 display: masonry 版本從資料欄變更為資料列,表示要變更 masonry-direction 的值。如果是格線版本,您需要切換 grid-template-columns 和 grid-template-rows 屬性的值。如果使用簡寫,請變更語法順序。
在這兩個切換流程範例中,display: masonry 版本都更直覺。單一屬性可控制流程 masonry-direction,並採用下列其中一個值:
rowcolumnrow-reversecolumn-reverse
然後,假設預設的自動值不符合需求,請將任何需要的尺寸資訊新增至 masonry-template-tracks。
使用格線時,如要反向,必須使用 grid-auto-flow 屬性;如要切換列的砌磚,則須切換 grid-template-* 屬性的值。此外,在目前的格線語法中,也無法將格線軸的值設為未定義。您一律需要在沒有 masonry 值的軸上指定 grid-template-* 屬性。
放置項目
在這兩個版本中,您都可以使用格線版面配置中熟悉的行式放置方式,明確放置項目。在這兩個版本中,您只能在格線軸中放置項目,也就是具有預先定義軌道的軸,您無法在執行砌磚版面配置的軸上放置項目。
前往 display: masonry
下列 CSS 定義了四欄的格狀配置。因此格線軸是資料欄。類別為 a 的項目會從第一個資料欄線放置到第三個資料欄線,並使用新的 masonry-track-* 屬性跨越兩個軌道。這也可以定義為 masonry-track: 1 / 3; 的簡寫。
.masonry {
display: masonry;
masonry-template-tracks: repeat(4, 1fr);
}
.a {
masonry-track-start: 1;
masonry-track-end: 3;
}
前往 display: grid
下列 CSS 定義了四欄的格狀配置。因此格線軸是資料欄。類別為 a 的項目會從第一欄線放置到第三欄線,並使用 grid-column-* 屬性跨越兩個軌道。這也可以定義為 grid-column: 1 / 3; 的簡寫。
如果格線軸是資料欄,系統會忽略 grid-row-* 屬性;如果格線軸是資料列,系統則會忽略 grid-columns-* 屬性。
.masonry {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
.a {
grid-column-start: 1;
grid-column-end: 3;
}
兩種語法都可以使用具名行。以下範例顯示含有兩條名為 a 的欄線的格線。
前往 display: masonry
具名行是在 masonry-template-tracks 的曲目清單值中定義。該項目可放在任何名為 a 的行之後。
.masonry {
display: masonry;
masonry-template-tracks: 100px [a] auto [a] auto 100px;
}
.item {
masonry-track: a;
}
前往 display: grid
這些具名行是在 grid-template-columns 的曲目清單值中定義。該項目會放在名為 a 的第一行之後。如果定義了 grid-row 屬性,系統會忽略該屬性。
.masonry {
display: grid;
grid-template-columns: 100px [a] auto [a] auto 100px;
grid-template-rows: masonry;
}
.item {
grid-column: a;
grid-row: a; /* ignored */
}
您也可以在這兩種語法中使用已命名的區域。以下範例顯示含有三個軌道的格線,分別命名為「a」、「b」和「c」。
前往 display: masonry
曲目名稱為 masonry-template-areas 的值。由於未定義任何軌道大小,因此這三者都會預設為 auto 大小。項目會放在「a」音軌中。
.masonry {
display: masonry;
masonry-template-areas: "a b c";
}
.item {
masonry-track: a;
}
定義資料列或資料欄時,這項操作的運作方式相同,唯一的差異是 masonry-direction 屬性。
前往 display: grid
資料欄的語法基本上完全相同。同樣地,由於未定義任何軌道大小,因此這三者都會預設為 auto 大小,但您仍需明確指出另一個軸為砌磚:
.masonry {
display: grid;
grid-template-areas: "a b c";
grid-template-rows: masonry;
}
.item {
grid-column: a;
}
不過,如果是資料列,值的寫法就不同了,因為 grid-template-areas 實際上是定義二維區域,每個資料列都會寫成個別字串:
.masonry {
display: grid;
grid-template-areas: "a" "b" "c"; /* Note the difference, each row is quoted. */
grid-template-columns: masonry;
}
.item {
grid-row: a;
}
這兩種做法的考量點
無論採用哪種定位方式,display: masonry 語法在切換方向時的效果都比較好。由於 masonry-track-* 屬性會沿著格線軸運作,因此如要變更方向,只要變更 masonry-direction 的值即可。使用格線版本時,至少需要備援屬性才能啟用切換功能。不過,請參閱先前的範例,瞭解使用格線版本時,變更方向會更加複雜。
速記
本文使用詳細屬性,清楚說明使用的屬性,但 display: masonry 和 display: grid 版本都可以使用簡寫定義。
前往 display: masonry
display: masonry 簡寫會使用 masonry 關鍵字。如要建立基本砌磚版面配置,請使用下列 CSS:
.masonry {
display: masonry;
masonry: repeat(3, 1fr);
}
如要建立簡單的資料列式磚塊版面配置,請按照下列步驟操作:
.masonry {
display: masonry;
masonry: row;
}
如要使用簡寫定義軌道和以資料列為準的版面配置,請執行下列操作:
.masonry {
display: masonry;
masonry: repeat(3, 1fr) row;
}
前往 display: grid
如要使用 grid 簡寫建立基本磚塊格線版面配置。
.masonry {
display: grid;
grid: masonry / repeat(3, 1fr);
}
如要建立簡單的資料列式磚塊版面配置,請按照下列步驟操作:
.masonry {
display: grid;
grid: repeat(3, auto) / masonry;
}
在較複雜的範例中,由於整體 display:masonry 語法較簡單,因此更多屬性可以一起封裝到簡寫中,而不會過於複雜。
舉例來說,假設您建立三個名為「a」、「b」和「c」的資料欄,並從底部開始填入資料。
前往 display:masonry
在 display: masonry 中,這三項屬性都可以透過簡寫一併設定:
.masonry {
display: masonry;
masonry: column-reverse "a b c";
}
由於大小是自動設定,因此您不需要指定大小,但如果想要特定大小,也可以新增。例如 masonry: column-reverse 50px 100px 200px "a b c";。
此外,每個元件都可以自由重新排序,不必記住特定順序。如要改為處理資料列,只要將 column-reverse 換成 row 或 row-reverse 即可,其餘語法不變。
前往 display: grid
在 display: grid 中,這三個層面必須分別設定:
.masonry {
display: grid;
grid-template-rows: masonry;
grid-template-areas: "a b c";
grid-auto-flow: wrap-reverse;
}
與砌磚範例一樣,這會將所有欄設為 auto 大小,但如果您想提供明確大小,可以這麼做:
.masonry {
display: grid;
grid: masonry / 50px 100px 200px;
grid-template-areas: "a b c";
grid-auto-flow: wrap-reverse;
}
或者,如要使用「grid」一併設定大小和區域名稱:
.masonry {
display: grid;
grid: "a b c" masonry / 50px 100px 200px;
grid-auto-flow: wrap-reverse;
}
在這兩個範例中,順序都必須嚴格遵守,如果想要改為列,順序就會不同。舉例來說,變更為資料列的樣子如下:
.masonry {
display: grid;
grid: 50px 100px 200px / masonry;
grid-template-areas: "a" "b" "c";
}
或者,您也可以將所有這些內容縮寫為:
.masonry {
display: grid;
grid: "a" 50px "b" 100px "c" 200px / masonry;
}
這兩種做法的考量點
display: masonry 簡寫形式相對簡單,因此很可能廣為使用。在許多情況下,如果是「標準」磚塊配置,您只要設定軌道定義即可;其他所有值都可以採用預設值。
display: grid 版本使用現有的 grid 簡寫,這是一種相當複雜的簡寫,根據我們的經驗,開發人員較少使用。如上述範例所示,即使是簡單的磚塊式版面配置,設定值的順序時也需要注意。
其他注意事項
本文將探討目前的一些常見用途,但我們不知道格線或磚塊在未來會如何發展。使用個別 display: masonry 語法的一大優點是,日後兩者可以分開。特別是初始值 (例如 masonry-template-tracks 的初始值),在砌磚版面中執行與格線不同的操作可能很有用。如果選擇 display: grid 版本,我們就無法變更格線預設值,這可能會限制日後可執行的操作。
在這些範例中,您可以看到瀏覽器必須忽略網格中有效的屬性 (如果使用砌磚)。舉例來說,在 grid-template-areas 中,大部分的值都會通過,因為它定義了二維格線版面配置,但在 Masonry 中,我們只會完整定義一個方向。
提供意見
請參閱這些範例,以及草案規格,其中列出各版本之間的差異。歡迎在第 9041 期問題中留言,或在自己的網誌或社群媒體上發文,並在 X 或 LinkedIn 上標記我們。