Tata letak “Cerdas” menggunakan kueri kontainer

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 ngomong1120pxLebar – 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 browserYang saya maksud bukan ukuran font utama di dokumen Anda, dan inilah alasannya1120pxPada contoh di atas, terjadi kesalahan.

Ukuran font yang mereka lihat merupakan ukuran font awal yang berasal dari browser sebelumnya<>setiapNilai diterapkan, termasuk gaya agen pengguna. Secara default, itu adalah16pxMeskipun 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…480pxLebar, dimanafont-sizeUkurannya 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 minimum300pxSaya tahu saya dapat memiliki tiga kolom saat wadahnya berada900pxlebarJika saya melakukannya dengan media query, itu tidak akan berhasil, karena ketika jendela tampilan saya900pxLebar, 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,chSempurna untuk hal semacam ini. menggunakanchSaya 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.

Opsi penyertaan CodePen alternatif

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:

Opsi penyertaan CodePen alternatif

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<>YangIni 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 bisaGunakan 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 adalah30chKita 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.

Opsi penyertaan CodePen alternatif

Meskipun mengubah warna latar belakang suatu hal bagus untuk demo, tentu saja kita dapat melakukan lebih banyak hal dengan ini:

Opsi penyertaan CodePen alternatif

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 iniPerubahan 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 bisaNamun, 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 menggunakanpxUntuk 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.

Opsi penyertaan CodePen alternatif

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 sudahpaddingSedangkan 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:

Opsi penyertaan CodePen alternatif

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.

Opsi penyertaan CodePen alternatif

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.

Sumber

-Advertisement-.

IDJ