Proposal alternatif untuk pemasangan batu CSS

Tim Chrome sangat ingin melihat implementasi tata letak jenis masonry di web. Namun, kami merasa bahwa menerapkannya sebagai bagian dari spesifikasi Petak CSS seperti yang diusulkan dalam postingan WebKit terbaru adalah sebuah kesalahan. Kami juga merasa bahwa postingan WebKit menentang versi masonry yang tidak diajukan oleh siapa pun.

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

  • Tim Chrome sangat ingin membuka pemblokiran masonry. Kami tahu ini adalah sesuatu yang diinginkan developer.
  • Menambahkan masonry ke spesifikasi grid bermasalah karena alasan selain apakah menurut Anda beton adalah grid atau tidak.
  • Penentuan masonry di luar spesifikasi petak tidak mencegah beberapa ukuran jalur untuk masonry, atau penggunaan properti seperti perataan atau celah, atau fitur lain yang digunakan dalam tata letak petak.

Haruskah masonry menjadi bagian dari kisi-kisi?

Tim Chrome yakin bahwa masonry harus menjadi metode tata letak terpisah, yang ditentukan menggunakan display: masonry (atau sebaiknya gunakan nama lain untuk memutuskan nama yang lebih baik). Nanti dalam postingan ini, Anda dapat melihat beberapa contoh tampilannya dalam kode.

Ada dua alasan terkait mengapa kami merasa bahwa masonry lebih baik didefinisikan di luar tata letak petak—potensi masalah performa tata letak, dan fakta bahwa masonry dan petak memiliki fitur yang dapat diterima di satu metode tata letak, tetapi tidak di metode yang lain.

Performa

Petak dan beton adalah hal yang berlawanan dalam hal cara browser menangani ukuran dan penempatan. Jika petak ditata, semua item ditempatkan sebelum tata letak dan browser tahu persis apa yang ada di setiap jalur. Hal ini memungkinkan pengaturan ukuran intrinsik yang kompleks yang sangat berguna dalam {i>grid<i}. Dengan masonry, item ditempatkan sebagaimana diletakkan, dan browser tidak tahu berapa banyak item di setiap trek. Hal ini bukan masalah pada semua trek berukuran intrinsik atau semua trek berukuran tetap, tetapi jika Anda menggabungkan trek tetap dan intrinsik. Untuk mengatasi masalah tersebut, browser perlu melakukan langkah pra-tata letak untuk menata letak setiap item dengan segala cara yang memungkinkan 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 mulai mengalami masalah. Masalah ini menjadi eksponensial setelah Anda menambahkan subgrid.

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

Apa yang kita lakukan pada hal-hal yang tidak masuk akal di setiap metode tata letak?

Ketika flexbox dan petak menjadi bagian dari CSS, developer sering merasa bahwa mereka berperilaku dengan cara yang tidak konsisten. Inkonsistensi yang mereka alami adalah karena asumsi 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 berada di flexbox, tidak semua metode penyelarasan tersedia, karena flexbox memiliki satu dimensi.

Membundel batu ke dalam petak akan memutus hubungan yang jelas antara konteks pemformatan dan ketersediaan hal-hal seperti properti perataan, yang ditentukan dalam spesifikasi Box Alignment per konteks pemformatan.

Jika kami memutuskan untuk menangani masalah performa yang diuraikan sebelumnya dengan menjadikan definisi trek tetap dan intrinsik campuran sebagai masonry, Anda harus mengingat bahwa pola yang sangat umum untuk tata letak petak tidak sesuai untuk masonry.

Ada juga pola yang cocok untuk beton, misalnya grid-template-columns: repeat(auto-fill, max-content), karena Anda tidak memiliki batasan silang, tetapi harus tetap tidak valid dalam petak. Berikut ini daftar properti yang diperkirakan akan berperilaku berbeda atau memiliki nilai valid yang berbeda.

  • grid-template-areas: Dalam masonry, Anda hanya dapat menentukan baris awal ke 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. Menggabungkan keduanya akan menimbulkan masalah yang tidak valid karena metode tata letak yang Anda gunakan.
  • Petak memiliki empat properti penempatan (grid-column-start dan seterusnya), masonry hanya memiliki dua properti.
  • Petak 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 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, baik untuk saat ini maupun di masa mendatang. Kami perlu memastikan bahwa semuanya memperhitungkan batu, dan apakah itu berfungsi atau tidak untuk beton. Ini juga membingungkan dari sudut pandang pengembang. Mengapa Anda harus mengingat bahwa meskipun menggunakan display: grid, beberapa hal tidak berfungsi karena penggunaan masonry?

Proposal alternatif

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

Tata letak masonry klasik

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

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

Trek dengan ukuran yang sama.

Gunakan ukuran trek jenis petak untuk lebar kolom yang berbeda

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

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

Pola trek berukuran lebar dan sempit.

Ukuran trek tambahan untuk beton

Ada opsi ukuran trek tambahan yang tidak kami izinkan dalam petak karena petak adalah metode tata letak dua dimensi. Ini akan berguna untuk batu, tetapi akan membingungkan jika mereka kemudian tidak bekerja di {i>grid<i}.

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 jalur dengan ukuran yang sama, berukuran otomatis untuk mengakomodasi trek terbesar.

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

Masonry dengan trek berukuran otomatis.

Izinkan konten untuk menjangkau kolom, dan tempatkan item di tata letak masonry

Tidak ada alasan untuk tidak memiliki konten yang mencakup kolom dalam spesifikasi masonry yang terpisah. Kode ini mungkin menggunakan properti masonry-track, yang merupakan singkatan untuk masonry-track-start dan masonry-track-end karena Anda hanya memiliki satu dimensi untuk membentang sesuatu saat berada di 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 barang yang ditempatkan dan membentang.

Sub-masonry atau subgrid yang mengadopsi trek batu

Hal ini dapat didukung dengan spesifikasi masonry yang terpisah, juga dengan ketentuan bahwa trek campuran intrinsik dan berukuran tetap tidak diizinkan. Persis seperti apa tampilannya yang perlu didefinisikan. Kita tidak melihat alasan bahwa ini tidak akan berhasil.

Kesimpulan

Kami ingin membahas spesifikasi yang dapat dikirim secara antar-operasi. Namun, kami ingin melakukannya dengan cara yang berfungsi dengan baik saat ini dan di masa depan, serta yang dapat diandalkan oleh developer. Satu-satunya cara untuk menangani masalah performa yang diuraikan, adalah menjadikan masalah kedua—yang memiliki bagian jaringan yang ilegal di bidang masonry—lebih buruk. Menurut kami itu bukan solusi yang bagus, terutama jika mungkin memiliki semua fitur petak yang Anda inginkan sekaligus mempertahankan hal-hal yang berbeda dengan jelas.

Jika Anda memiliki masukan, bergabunglah dalam diskusi di Masalah 9041.

Terima kasih kepada Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick, dan Chris Harrelson untuk meninjau postingan ini dan diskusi yang menjadi dasar.