CSS 磚石的替代提案

發布日期:2024 年 4 月 30 日,上次更新日期:2026 年 2 月 13 日

Chrome 團隊很希望看到網頁上導入砌磚式版面配置。不過,我們認為將其做為 CSS 格線規格的一部分來實作,如最近的 WebKit 貼文中所述,是錯誤的做法。我們也認為,WebKit 貼文反對的是無人提議的格線配置版本。

因此,本文旨在說明 Chrome 團隊對實作 CSS 格線版面配置規格的砌石版面配置有何疑慮,並明確說明替代提案的用途。簡單來說,

  • Chrome 團隊非常希望解除 Masonry 的封鎖,我們知道這是開發人員的需求。
  • 除了你是否認為磚塊排列是格線之外,將磚塊排列新增至格線規格也有其他問題。
  • 在格線規格以外定義砌磚,不會阻止砌磚使用多個軌道大小,也不會阻止使用對齊或間隙等屬性,或格線版面配置中使用的任何其他功能。

是否應將磚塊排列納入格線?

Chrome 團隊認為,格狀配置應為獨立的版面配置方法,並使用 display: masonry 定義 (或使用其他關鍵字,如果決定採用更合適的名稱)。本文稍後會提供一些程式碼範例,說明這類函式在程式碼中的樣貌。

我們認為在格線版面配置之外定義 Masonry 較為合適,有兩個相關原因:版面配置效能問題的可能性,以及 Masonry 和格線都有適合其中一種版面配置方法但不適合另一種的功能。

成效

就瀏覽器處理大小和放置位置的方式而言,格線和砌磚是相反的。版面配置格線時,所有項目都會先放置在版面配置之前,瀏覽器會確切知道每個軌道中的內容。這項功能可啟用複雜的內建大小調整功能,在格線中非常實用。使用砌磚時,項目會按照版面配置放置,瀏覽器不知道每個軌道中有多少項目。這並非所有內建大小軌或所有固定大小軌的問題,但如果您混合使用固定和內建軌,就會發生這種情況。為解決這個問題,瀏覽器需要執行預先版面配置步驟,以各種可能的方式配置每個項目來取得測量結果。如果格線很大,這會導致版面配置效能問題。

因此,如果您有軌道定義為 grid-template-columns: 200px auto 200px 的砌石版面配置 (這是格線中非常常見的做法),就會開始遇到問題。新增子格後,這些問題會以指數形式增加

有人認為大多數人不會遇到這個問題,但我們已經知道使用者確實有非常大的格線。我們不希望推出使用限制較多的產品,因為有替代方法。

如果每個版面配置方法中都有不合理之處,該怎麼辦?

當彈性方塊和格線成為 CSS 的一部分時,開發人員往往覺得兩者的行為不一致。他們長期以來都假設版面配置是根據區塊版面配置運作,因此才會遇到不一致的問題。隨著時間推移,開發人員開始瞭解格式化內容。切換至格線或彈性格式化環境時,某些項目的行為會有所不同。舉例來說,您知道在彈性方塊中,並非所有對齊方式都適用,因為彈性方塊是一維的。

將 Masonry 併入格線會破壞格式化環境與對齊屬性等項目可用性之間的明確連結,這些項目是根據格式化環境在 Box Alignment 規格中定義。

如果我們決定處理先前所述的效能問題,在砌磚中將混合內建和固定軌定義設為違法,您就必須記住,網格版面配置的常見模式不適用於砌磚。

此外,在砌磚格線中也有合理的模式,例如 grid-template-columns: repeat(auto-fill, max-content),因為您沒有交叉限制,但必須在格線中保持無效。以下列出預期行為不同或有效值不同的屬性。

  • grid-template-areas:在磚塊排列中,您只能在非磚塊排列方向指定初始資料列。
  • grid-template:速記符號必須考量所有差異。
  • 由於合法值不同,請追蹤 grid-template-columnsgrid-template-rows 的大小值。
  • grid-auto-flow不適用於磚塊式版面配置,masonry-auto-flow則不適用於格線。合併後,由於您使用的版面配置方法,會導致無效項目產生問題。
  • 格線有四個刊登位置屬性 (grid-column-start 等),而砌磚只有兩個。
  • 格線可以使用所有六個 justify-*align-* 屬性,但 Masonry 僅使用子集,例如 Flexbox。

此外,開發人員在 grid-with-masonry 或 grid-without-masonry 中使用無效值時,會導致新的錯誤情況,因此您也必須指定所有這些情況的處理方式。舉例來說,您可以使用 grid-template-columns: masonrygrid-template-rows: masonry,但不能同時使用兩者。如果同時使用這兩項功能,會發生什麼情況?必須指定這些詳細資料,所有瀏覽器才會執行相同動作。

從規格的角度來看,這一切現在和未來都會變得複雜。我們需要確保所有項目都考量到 Masonry,以及是否適用於 Masonry。對開發人員來說,這也令人困惑。為什麼要記住,儘管使用 display: grid,但由於使用砌磚,有些項目無法運作?

替代提案

如前所述,Chrome 團隊希望在格線規格以外定義砌磚。這不代表只能使用非常簡單的版面配置方法,且欄位大小必須相同。WebKit 貼文中的所有試用版仍可使用。

傳統石造工程版面配置

說到砌磚,大多數人會想到多個大小相等的直欄。這會使用下列 CSS 定義,需要的程式碼比對應的格線組合版本少一行。

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

大小相同的音軌。

使用格線型軌道大小,設定不同欄寬

除了先前提到混合使用內建和固定軌道大小的問題,您可以使用格線中所有喜愛的軌道大小。例如 WebKit 網誌文章中的範例,即為重複的窄欄和寬欄模式。

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

寬窄軌道的模式。

格狀配置的其他軌道大小

由於格線是二維版面配置方法,因此我們不允許在格線中使用其他軌道大小選項。這些屬性在砌磚版面配置中很有用,但如果無法在格線中使用,就會造成混淆。

自動填滿 max-content 大小的軌道。

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

自動填滿 auto 大小的軌道,建立大小相同的軌道,並自動調整大小以容納最大的軌道。

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

自動調整大小的軌道。

允許內容跨越欄位,並將項目放置在磚塊式版面配置中

沒有理由不讓內容跨越多個資料欄,只要在獨立的砌磚規格中即可。這可能會使用 masonry-track 屬性,因為當您位於格狀配置中時,只有一個維度可以跨越事物,因此這是 masonry-track-startmasonry-track-end 的簡寫。

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

放置和跨距項目。

採用砌塊格線軌的子砌塊或子格線

這項功能可透過獨立的砌磚規格支援,但同樣須遵守混合內建和固定大小軌道不允許的規定。具體來說,這類資料的樣貌需要定義。我們認為這項功能應該可以正常運作。

結論

我們希望規格能達到可互通運送的程度。不過,我們希望以現在和未來都能順利運作的方式進行,並讓開發人員信賴。如要解決上述效能問題,唯一的方法是讓第二個問題 (即砌石格線的部分違規) 更加嚴重。我們認為這不是好方法,尤其是在清楚區隔不同項目時,可以保留所有想要的格線功能。

如有任何意見,歡迎加入問題 9041 的討論。

感謝 Bramus、Tab Atkins-Bittner、Una Kravets、Ian Kilpatrick 和 Chris Harrelson 審查這篇文章,並參與相關討論。