Proposal alternatif untuk pemasangan batu CSS

Dipublikasikan: 30 April 2024, Terakhir diperbarui: 13 Februari 2026

Tim Chrome sangat ingin melihat penerapan tata letak jenis masonry di web. Namun, kami merasa bahwa menerapkannya sebagai bagian dari spesifikasi CSS Grid seperti yang diusulkan dalam postingan WebKit baru-baru ini akan menjadi kesalahan. Kami juga merasa bahwa postingan WebKit menentang versi tata letak petak yang tidak diusulkan oleh siapa pun.

Oleh karena itu, postingan ini bertujuan untuk menjelaskan alasan kami di Chrome memiliki kekhawatiran tentang penerapan tata letak masonry sebagai bagian dari spesifikasi Tata Letak Petak CSS, dan mengklarifikasi secara tepat apa yang memungkinkan proposal alternatif. Singkatnya:

  • Tim Chrome sangat ingin membuka blokir tata letak masonry, kami tahu bahwa ini adalah sesuatu yang diinginkan developer.
  • Menambahkan tata letak bata ke spesifikasi petak menimbulkan masalah karena alasan lain selain apakah Anda menganggap tata letak bata adalah petak atau bukan.
  • Menentukan tata letak masonry di luar spesifikasi petak tidak mencegah beberapa ukuran jalur untuk tata letak masonry, atau penggunaan properti seperti perataan atau jarak, atau fitur lain yang digunakan dalam tata letak petak.

Haruskah tata letak bata menjadi bagian dari petak?

Tim Chrome yakin bahwa tata letak masonry harus menjadi metode tata letak terpisah, yang ditentukan menggunakan display: masonry (atau kata kunci lain jika nama yang lebih baik diputuskan). Di bagian selanjutnya dalam postingan ini, Anda dapat melihat beberapa contoh tampilannya dalam kode.

Ada dua alasan terkait mengapa kami merasa tata letak masonry lebih baik ditentukan di luar tata letak petak—potensi masalah performa tata letak, dan fakta bahwa masonry dan petak memiliki fitur yang masuk akal dalam satu metode tata letak, tetapi tidak dalam metode tata letak lainnya.

Performa

Tata letak petak dan masonry berlawanan dalam hal cara browser menangani ukuran dan penempatan. Saat petak ditata, semua item ditempatkan sebelum tata letak dan browser mengetahui persis apa yang ada di setiap jalur. Hal ini memungkinkan ukuran intrinsik yang kompleks dan sangat berguna dalam petak. Dengan tata letak bata, item ditempatkan sebagaimana ditata, dan browser tidak mengetahui jumlah item di setiap jalur. Hal ini bukan masalah pada semua jalur berukuran intrinsik atau semua jalur berukuran tetap, tetapi akan menjadi masalah jika Anda mencampur jalur tetap dan intrinsik. Untuk mengatasi masalah ini, browser perlu melakukan langkah pra-tata letak untuk menata setiap item dengan setiap cara yang memungkinkan untuk mendapatkan pengukuran. Dengan petak yang besar, hal ini akan menyebabkan masalah performa tata letak.

Oleh karena itu, jika Anda memiliki tata letak masonry dengan definisi jalur grid-template-columns: 200px auto 200px—hal yang sangat umum dilakukan dalam petak—Anda akan mulai mengalami masalah. Masalah ini menjadi eksponensial setelah Anda menambahkan subgrid.

Ada argumen bahwa sebagian besar orang tidak akan mengalami masalah ini, tetapi kami sudah mengetahui bahwa orang memang memiliki petak yang sangat besar. Kami tidak ingin mengirimkan sesuatu yang memiliki batasan dalam penggunaannya, jika ada pendekatan alternatif.

Apa yang kita lakukan terhadap hal-hal yang tidak masuk akal dalam setiap metode tata letak?

Saat flexbox dan petak menjadi bagian dari CSS, developer sering kali merasa bahwa keduanya berperilaku secara tidak konsisten. Ketidakkonsistenan yang mereka alami disebabkan oleh asumsi yang sudah lama tentang cara kerja tata letak, berdasarkan tata letak blok. Seiring waktu, developer mulai memahami konteks pemformatan. Saat kita beralih ke konteks pemformatan petak atau fleksibel, beberapa hal akan berperilaku berbeda. Misalnya, Anda tahu bahwa saat Anda berada di flexbox, tidak semua metode perataan tersedia, karena flexbox bersifat satu dimensi.

Menggabungkan tata letak masonry ke dalam tata letak petak akan merusak hubungan yang jelas antara konteks pemformatan dan ketersediaan hal-hal seperti properti perataan, yang ditentukan dalam spesifikasi Perataan Kotak per konteks pemformatan.

Jika kami memutuskan untuk mengatasi masalah performa yang diuraikan sebelumnya dengan melarang definisi jalur tetap dan intrinsik campuran dalam tata letak masonry, Anda harus ingat bahwa pola tata letak petak yang sangat umum tidak berfungsi untuk tata letak masonry.

Ada juga pola yang akan masuk akal dalam tata letak masonry, misalnya grid-template-columns: repeat(auto-fill, max-content), karena Anda tidak memiliki batasan silang, tetapi harus tetap tidak valid dalam tata letak petak. Berikut adalah daftar properti yang kami harapkan berperilaku berbeda atau memiliki nilai valid yang berbeda.

  • grid-template-areas: Dalam tata letak petak, Anda hanya dapat menentukan baris awal dalam arah non-petak.
  • grid-template: Singkatan harus memperhitungkan semua perbedaan.
  • Lacak nilai ukuran untuk grid-template-columns dan grid-template-rows karena perbedaan nilai yang sah.
  • grid-auto-flow tidak berlaku untuk tata letak masonry dan masonry-auto-flow tidak berlaku untuk tata letak petak. Menggabungkannya akan menimbulkan masalah pada hal-hal yang tidak valid karena metode tata letak yang Anda gunakan.
  • Petak memiliki empat properti penempatan (grid-column-start dan seterusnya), masonry hanya memiliki dua.
  • Grid dapat menggunakan keenam properti justify-* dan align-*, tetapi Masonry hanya menggunakan subset seperti flexbox.

Selain itu, akan ada persyaratan untuk menentukan apa yang terjadi dalam semua kasus error baru yang disebabkan oleh developer yang menggunakan nilai yang tidak valid dalam grid-with-masonry atau grid-without-masonry. Misalnya, Anda dapat menggunakan grid-template-columns: masonry atau grid-template-rows: masonry, tetapi tidak keduanya sekaligus. Apa yang terjadi jika Anda menggunakan keduanya sekaligus? Detail ini harus ditentukan agar semua browser melakukan hal yang sama.

Semua ini menjadi rumit dari sudut pandang spesifikasi, sekarang dan pada masa mendatang. Kita harus memastikan bahwa semuanya mempertimbangkan tata letak masonry, dan apakah tata letak tersebut berfungsi atau tidak dalam tata letak masonry. Hal ini juga membingungkan dari sudut pandang developer. Mengapa Anda harus mengingat bahwa meskipun menggunakan display: grid, beberapa hal tidak berfungsi karena menggunakan tata letak masonry?

Proposal alternatif

Seperti yang telah disebutkan, tim Chrome ingin menentukan tata letak masonry di luar spesifikasi petak. Hal ini tidak berarti bahwa tata letak akan terbatas pada metode tata letak yang sangat sederhana dengan ukuran kolom yang identik. Semua demo dalam postingan WebKit masih dapat dilakukan.

Tata letak susunan batu klasik

Saat memikirkan tata letak masonry, kebanyakan orang membayangkan tata letak dengan beberapa kolom berukuran sama. Hal ini akan ditentukan menggunakan CSS berikut, yang memerlukan kode satu baris lebih sedikit daripada versi yang dibundel grid yang setara.

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

Trek berukuran sama.

Menggunakan ukuran trek jenis petak untuk lebar kolom yang berbeda

Selain masalah yang disebutkan sebelumnya terkait ukuran trek tetap dan intrinsik campuran, Anda dapat menggunakan semua ukuran trek yang Anda sukai dari petak. Seperti contoh dari postingan blog WebKit, pola kolom sempit dan lebar yang berulang.

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

Pola jalur berukuran lebar dan sempit.

Pengukuran jalur tambahan untuk tata letak masonry

Ada opsi ukuran trek tambahan yang tidak kami izinkan dalam petak karena petak adalah metode tata letak dua dimensi. Hal ini akan berguna dalam tata letak masonry, tetapi akan membingungkan jika tidak berfungsi dalam tata letak petak.

Mengisi otomatis trek berukuran max-content.

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

Mengisi otomatis trek berukuran auto, yang akan membuat trek dengan ukuran yang sama, dan disesuaikan secara otomatis untuk mengakomodasi trek yang terbesar.

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

Masonry dengan jalur berukuran otomatis.

Mengizinkan konten mencakup kolom, dan menempatkan item pada tata letak masonry

Tidak ada alasan untuk tidak memiliki konten yang mencakup kolom dalam spesifikasi tata letak terpisah. Hal ini dapat menggunakan properti masonry-track, yang merupakan singkatan dari masonry-track-start dan masonry-track-end karena Anda hanya memiliki satu dimensi untuk merentangkan hal-hal saat berada dalam tata letak masonry.

.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 */
}

Masonry dengan item yang ditempatkan dan direntangkan.

Sub-masonry atau subgrid yang mengadopsi jalur masonry

Hal ini dapat didukung dengan spesifikasi tata letak bata terpisah, sekali lagi dengan persyaratan bahwa jalur berukuran tetap dan intrinsik campuran tidak diizinkan. Tampilan yang tepat harus ditentukan. Kami tidak melihat alasan mengapa hal ini tidak akan berhasil.

Kesimpulan

Kami ingin mencapai titik spesifikasi yang dapat dikirimkan secara interoperabilitas. Namun, kami ingin melakukannya dengan cara yang berfungsi dengan baik sekarang dan pada masa mendatang, serta dapat diandalkan oleh developer. Satu-satunya cara untuk mengatasi masalah performa yang diuraikan adalah dengan memperparah masalah kedua—yaitu memiliki bagian petak yang tidak valid dalam tata letak masonry. Kami tidak menganggap itu solusi yang baik, terutama jika Anda dapat memiliki semua fitur petak yang Anda inginkan sambil memisahkan dengan jelas hal-hal yang berbeda.

Jika ada masukan, bergabunglah dalam diskusi di Issue 9041.

Terima kasih kepada Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick, dan Chris Harrelson atas peninjauan postingan ini dan diskusi yang mendasarinya.