CSS modern terus memberi kita banyak cara baru dan lebih mudah untuk menyelesaikan masalah lama, namun sering kali fitur baru yang kita dapatkan tidak hanya menyelesaikan masalah lama, tetapi juga membuka kemungkinan baru.
Kueri kontainer adalah salah satu hal yang membuka kemungkinan-kemungkinan baru, namun karena hal tersebut terlihat <>banyak> Seperti halnya cara lama dalam menangani pertanyaan media, naluri pertama kita adalah menggunakannya dengan cara yang sama, atau setidaknya dengan cara yang sangat mirip.
Namun, ketika kami melakukan ini, kami tidak memanfaatkan betapa “pintarnya” kueri kontainer jika dibandingkan dengan kueri media!
-Advertisement-.
Mengingat pentingnya pertanyaan media dalam mengantarkan era desain web responsif, saya tidak ingin mengatakan hal buruk tentang hal itu… tetapi pertanyaan media itu bodoh. Dia tidak bodoh dalam konsepnya, tapi dia bodoh karena dia tidak tahu banyak. Faktanya, kebanyakan orang berasumsi bahwa mereka tahu lebih banyak daripada yang sebenarnya.
Mari gunakan contoh sederhana ini untuk mengilustrasikan apa yang saya maksud:
html {
font-size: 32px;
}
body {
background: lightsalmon;
}
@media (min-width: 35rem) {
body {
background: lightseagreen;
}
}
Berapa ukuran jendela tampilan yang warna latar belakangnya akan diubah? kalo ngomong1120px
Lebar – yaitu 35 kali 32 bagi yang tidak mau bersusah payah menghitung – Anda tidak sendirian dalam tebakan ini, tetapi Anda juga salah.
Ingat ketika saya mengatakan pertanyaan media tidak tahu banyak? Hanya ada dua hal yang mereka ketahui:
- Melihat ukuran jendela, dan
- Ukuran font di browser.
Dan ketika saya berkata<>Ukuran font di browser>Yang saya maksud bukan ukuran font utama di dokumen Anda, dan inilah alasannya1120px
Pada contoh di atas, terjadi kesalahan.
Ukuran font yang mereka lihat merupakan ukuran font awal yang berasal dari browser sebelumnya<>setiap>Nilai diterapkan, termasuk gaya agen pengguna. Secara default, itu adalah16px
Meskipun pengguna dapat mengubahnya di pengaturan browser mereka.
Dan ya,Ini disengaja. Spesifikasi kueri media menyatakan:
Satuan panjang relatif dalam kueri media didasarkan pada nilai awal, artinya satuan tersebut tidak pernah bergantung pada hasil iklan.
Ini mungkin tampak seperti keputusan yang aneh, namun jika tidak berhasil, apa yang akan terjadi jika kita melakukan ini:
html {
font-size: 16px;
}
@media (min-width: 30rem) {
html {
font-size: 32px;
}
}
Jika media query melihat ke rootfont-size
(Seperti yang diasumsikan kebanyakan orang, Anda akan menemukan loop ketika jendela tampilan mencapai…480px
Lebar, dimanafont-size
Ukurannya akan bertambah, lalu mengecil lagi dan lagi.
Kueri kontainer kini menjadi lebih cerdas
Meskipun kueri media memiliki batasan ini, dan untuk alasan yang bagus, kueri kontainer tidak perlu mengkhawatirkan masalah seperti ini, dan ini membuka banyak kemungkinan menarik!
Misalnya, kita memiliki kotak yang perlu ditumpuk dengan ukuran lebih kecil, tetapi tiga kolom dengan ukuran lebih besar. Dengan pertanyaan media, kita harus menemukan angka ajaib untuk mencapai titik yang tepat di mana hal itu perlu terjadi. Dengan menggunakan kueri kontainer, kita bisa menentukan ukuran kolom minimum yang kita inginkan, dan ini akan selalu berhasil karena kita melihat ukuran kontainer.
Artinya kita tidak memerlukan angka ajaib untuk breakpoint.Jika Anda ingin tiga kolom dengan ukuran minimum300px
Saya tahu saya dapat memiliki tiga kolom saat wadahnya berada900px
lebarJika saya melakukannya dengan media query, itu tidak akan berhasil, karena ketika jendela tampilan saya900px
Lebar, wadah saya seringkali lebih kecil dari itu.
Namun lebih baik lagi, kita juga bisa menggunakan unit apa pun yang kita inginkanKarena kueri kontainer, tidak seperti kueri media, dapat melihat ukuran font kontainer itu sendiri.
untukku,ch
Sempurna untuk hal semacam ini. menggunakanch
Saya dapat mengatakan “Jika saya memiliki cukup ruang untuk setiap kolom dengan lebar minimal 30 karakter, saya ingin tiga kolom.”
Kita bisa menghitungnya sendiri di sini seperti ini:
.grid-parent { container-type: inline-size; }
.grid {
display: grid;
gap: 1rem;
@container (width > 90ch) {
grid-template-columns: repeat(3, 1fr);
}
}
Ini bekerja dengan sangat baik, seperti yang Anda lihat pada contoh ini.
Sebagai bonus lainnya, terima kasih kepada Miriam Suzanne, baru-baru ini saya mengetahui bahwa Anda dapat menyertakannyacalc()
Di dalam media queries dan container, jadi daripada melakukan perhitungan sendiri, Anda bisa memasukkannya seperti ini:@container (width > calc(30ch * 3))
Seperti yang Anda lihat dalam contoh ini:
Kasus penggunaan yang lebih praktis
Salah satu hal yang mengganggu tentang penggunaan kueri kontainer adalahAnda harus memiliki wadah khususKontainer tidak dapat membuat kueri sendiri, jadi kita memerlukan pembungkus tambahan pada elemen yang ingin kita pilih menggunakan kueri kontainer. Anda dapat melihat pada contoh di atas bahwa saya memerlukan wadah di luar jaringan saya agar ini dapat berfungsi.
Yang lebih menyebalkan lagi adalah ketika Anda ingin anak-anak jaringan atau elastis mengubah tata letaknya sesuai dengan ruang penyimpanan yang mereka miliki, hanya untuk menyadari bahwa ini tidak akan berfungsi jika induknya adalah wadahnya. Alih-alih jaringan atau wadah elastis menjadi wadah yang ditentukan, kita akhirnya harus…Bungkus setiap elemen jaring atau elastis dalam wadahSeperti dia:
<div class="grid">
<div class="card-container">
<div class="card">
</div>
<div class="card-container">
<div class="card">
</div>
<div class="card-container">
<div class="card">
</div>
</div>
.card-container { container-type: inline-size; }
itu tidak<>Yang>Ini adalah hal yang buruk dalam skema besar, tapi itu agak menjengkelkan.
Namun, ada cara untuk mengatasinya!
Misalnya saja jika Anda menggunakanrepeat(auto-fit, ...)
Anda<>Dia bisa>Gunakan mainnet sebagai wadah!
.grid-auto-fit {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(min(30ch, 100%)), 1fr);
container-type: inline-size;
}
Mengetahui bahwa ukuran kolom minimum adalah30ch
Kita dapat memanfaatkan informasi ini untuk mendesain ulang setiap elemen grid tergantung pada berapa banyak kolom yang kita miliki:
/* 2 columns + gap */
@container (width > calc(30ch * 2 + 1rem)) { ... }
/* 3 columns + gaps */
@container (width > calc(30ch * 3 + 2rem)) { ... }
Saya menggunakan ini dalam contoh ini untuk mengubah gaya anak pertama di kisi saya berdasarkan apakah kita memiliki satu, dua, atau tiga kolom.
Meskipun mengubah warna latar belakang suatu hal bagus untuk demo, tentu saja kita dapat melakukan lebih banyak hal dengan ini:
Sisi negatif dari pendekatan ini
Satu-satunya kelemahan yang saya temukan saat menggunakan pendekatan ini adalah kita tidak dapat menggunakan properti khusus untuk breakpoint, yang akan sangat meningkatkan DX untuk ini.
Ini seharusnya<>baru-baru ini>Perubahan yang dipertimbangkan untuk kueri media khusus ada di editor draf spesifikasi untuk spesifikasi Media Query Level 5, namun perubahan tersebut sudah ada di sana selama beberapa waktu tanpa tindakan apa pun dari browser apa pun, jadi mungkin memerlukan waktu lama sebelum kami dapat menggunakannya.
Meskipun pendapat saya adalah bahwa memiliki properti khusus untuk elemen-elemen ini akan membuatnya lebih mudah dibaca dan diperbarui, hal ini membuka cukup banyak kemungkinan bahwa tidak ada gunanya tanpa mereka.
Bagaimana dengan flexbox?
Dengan flexbox, elemen flexlah yang menentukan tata letaknya, jadi agak aneh jika ukuran yang kita terapkan pada elemen itulah yang penting pada breakpoint.
Dia – dia<>Dia bisa>Namun, ini masih berfungsi Ada masalah besar yang bisa muncul jika Anda melakukan ini menggunakan flexboxSebelum kita melihat masalahnya, berikut adalah contoh singkat cara membuatnya berfungsi menggunakan flexbox:
.flex-container {
display: flex;
gap: 1rem;
flex-wrap: wrap;
container-type: inline-size;
}
.flex-container > * {
/* full-width at small sizes */
flex-basis: 100%;
flex-grow: 1;
/* when there is room for 3 columns including gap */
@container (width > calc(200px * 3 + 2rem)) {
flex-basis: calc(200px);
}
}
Dalam hal ini, saya menggunakanpx
Untuk menunjukkan bahwa ini berfungsi juga, tetapi Anda dapat menggunakan modul apa pun di luar sana, seperti yang saya lakukan dengan contoh grid.
Ini mungkin terdengar seperti sesuatu yang dapat Anda gunakan juga untuk kueri media — Anda dapat menggunakannyacalc()
Di dalamnya juga! — tetapi ini hanya akan berfungsi jika elemen induk memiliki lebar yang cocok dengan lebar area pandang, dan hal ini tidak sering terjadi.
Hal ini terjadi jika elemen elastis mengandung bantalan
Tidak banyak orang yang menyadari hal ini, namun algoritma Flexbox tidak memperhitungkan padding atau border, bahkan jika Anda mengubahnyabox-sizing
. kalau sudahpadding
Sedangkan untuk item fleksibilitas Anda, pada dasarnya Anda harus memberi nomor secara ajaib agar dapat berfungsi.
Berikut adalah contoh di mana saya menambahkan beberapa padding tetapi tidak mengubah apa pun, dan Anda akan melihat salah satu tata letak dua kolom yang canggung dengan salah satunya memanjang ke bawah pada satu titik:
Karena itu, saya biasanya lebih sering menggunakan pendekatan jenis ini dengan grid daripada flexbox, tetapi pasti ada situasi di mana pendekatan ini masih bisa berfungsi.
Seperti sebelumnya, karena kita mengetahui berapa banyak kolom yang kita miliki, kita dapat memanfaatkannya untuk membuat tata letak yang lebih dinamis dan menarik bergantung pada ruang yang tersedia untuk elemen atau elemen tertentu.
Buka beberapa kemungkinan menarik
Saya baru saja mulai bermain-main dengan hal semacam ini, dan saya menemukan bahwa hal ini membuka beberapa kemungkinan baru yang sebelumnya tidak tersedia bagi kita melalui pertanyaan media, dan ini membuat saya bersemangat untuk melihat kemungkinan lain!
Tata Letak Cerdas menggunakan Kueri Kontainer awalnya diterbitkan di CSS-Tricks, bagian dari keluarga DigitalOcean. Anda harus mendapatkan buletin.