Proposal alternatif untuk pemasangan batu CSS

Tim Chrome ingin melihat implementasi tata letak jenis masonry di web. Namun, kami merasa bahwa menerapkannya sebagai bagian dari spesifikasi CSS Grid seperti yang diusulkan dalam postingan WebKit terbaru adalah sebuah kesalahan. Kami juga merasa bahwa postingan WebKit tersebut menentang versi masonry yang tidak ada yang mengusulkannya.

Oleh karena itu, postingan ini bertujuan untuk menjelaskan mengapa kami di Chrome memiliki kekhawatiran tentang menerapkan masonry sebagai bagian dari spesifikasi Tata Letak Petak CSS, dan menjelaskan secara tepat apa yang diaktifkan oleh proposal alternatif. Singkatnya:

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

Apakah pasangan bata harus menjadi bagian dari petak?

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

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

Performa

Petak dan batu bata berlawanan dalam hal cara browser menangani ukuran dan penempatan. Saat petak ditata, semua item ditempatkan sebelum tata letak dan browser mengetahui dengan tepat apa yang ada di setiap jalur. Hal ini memungkinkan penskalaan intrinsik yang kompleks dan sangat berguna dalam petak. Dengan masonry, item ditempatkan seperti yang ditata, dan browser tidak tahu jumlahnya di setiap jalur. Hal ini tidak menjadi masalah dengan semua jalur berukuran intrinsik atau semua jalur berukuran tetap, tetapi menjadi masalah jika Anda mencampurkan jalur tetap dan intrinsik. Untuk mengatasi masalah ini, browser perlu melakukan langkah pra-tata letak dengan menata setiap item dengan segala cara untuk mendapatkan pengukuran, dengan petak besar, hal ini akan berkontribusi pada 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 sub-petak.

Ada argumen bahwa sebagian besar orang tidak akan mengalami hal ini, tetapi kita sudah mengetahui bahwa orang memang memiliki grid yang sangat besar. Kami tidak ingin mengirimkan sesuatu yang memiliki batasan cara penggunaannya, jika ada pendekatan alternatif.

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

Saat flexbox dan petak menjadi bagian dari CSS, developer sering merasa bahwa flexbox dan petak berperilaku secara tidak konsisten. Inkonsistensi yang mereka alami adalah karena asumsi yang sudah lama dipegang 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 secara berbeda. Misalnya, Anda tahu bahwa saat berada di flexbox, tidak semua metode perataan tersedia, karena flexbox bersifat satu dimensi.

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

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

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

  • grid-template-areas: Dalam masonry, Anda hanya dapat menentukan baris awal dalam arah non-masonry.
  • grid-template: Singkatan harus memperhitungkan semua perbedaan.
  • Melacak nilai ukuran untuk grid-template-columns dan grid-template-rows karena perbedaan nilai hukum.
  • grid-auto-flow tidak berlaku untuk masonry dan masonry-auto-flow tidak berlaku untuk 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), susunan bata hanya memiliki dua.
  • Petak dapat menggunakan keenam properti justify-* dan align-*, tetapi Masonry hanya menggunakan subset seperti flexbox.

Akan ada juga persyaratan untuk menentukan apa yang terjadi di semua kasus error baru yang disebabkan oleh developer yang menggunakan nilai yang tidak valid di petak dengan susunan atau petak tanpa susunan. 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.

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

Proposal alternatif

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

Tata letak pasangan batu klasik

Saat kebanyakan orang memikirkan masonry, mereka memikirkan tata letak dengan beberapa kolom berukuran sama. Ini akan ditentukan menggunakan CSS berikut, yang memerlukan kode tanpa baris daripada versi grid yang dipaketkan yang setara.

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

Jalur dengan ukuran yang sama.

Menggunakan ukuran jalur jenis petak untuk berbagai lebar kolom

Selain masalah yang disebutkan sebelumnya dengan ukuran jalur intrinsik dan tetap campuran, Anda dapat menggunakan semua ukuran jalur 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 masonry

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

Mengisi otomatis jalur 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, diukur secara otomatis untuk mengakomodasi trek terbesar.

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

Masonry dengan jalur yang diukur otomatis.

Mengizinkan konten untuk meluas ke kolom, dan menempatkan item pada tata letak masonry

Tidak ada alasan untuk tidak memiliki kolom yang mencakup konten dalam spesifikasi masonry terpisah. Ini mungkin menggunakan properti masonry-track, yang merupakan singkatan dari masonry-track-start dan masonry-track-end karena Anda hanya memiliki satu dimensi untuk memperluas berbagai 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 terbentang.

Sub-masonry atau sub-petak yang mengadopsi jalur masonry

Hal ini dapat didukung dengan spesifikasi masonry terpisah, lagi-lagi dengan ketentuan bahwa campuran jalur intrinsik dan berukuran tetap 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 dikirim secara interoperabilitas. Namun, kami ingin melakukannya dengan cara yang berfungsi dengan baik sekarang dan di masa mendatang, serta dapat diandalkan oleh developer. Satu-satunya cara untuk mengatasi masalah performa yang diuraikan adalah dengan memperburuk masalah kedua—yaitu memiliki bagian petak yang ilegal dalam masonry. Kami tidak yakin itu adalah solusi yang baik, terutama jika Anda dapat memiliki semua fitur petak yang Anda inginkan sekaligus menjaga agar hal-hal yang berbeda tetap terpisah dengan jelas.

Jika ada masukan, bergabunglah dalam diskusi di Masalah 9041.

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