Memulai Kueri Gaya

Kemampuan untuk mengkueri ukuran inline induk, dan nilai unit kueri container baru-baru ini telah mencapai dukungan yang stabil di semua mesin browser modern.

Dukungan Browser

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Sumber

Namun, spesifikasi pembatasan tidak hanya mencakup kueri ukuran; itu juga memungkinkan kueri nilai gaya induk. Mulai Chromium 111, Anda dapat menerapkan pembatasan gaya untuk nilai properti kustom dan mengkueri elemen induk untuk nilai properti kustom.

Dukungan Browser

  • Chrome: 111.
  • Edge: 111.
  • Firefox: tidak didukung.
  • Safari: 18.

Sumber

Artinya, kita memiliki kontrol gaya yang lebih logis dalam CSS, dan memungkinkan pemisahan logika aplikasi dan lapisan data yang lebih baik dari gayanya.

Spesifikasi CSS Containment Module Level 3, yang mencakup kueri ukuran dan gaya, memungkinkan tiap gaya dikueri dari induk, termasuk pasangan properti dan nilai seperti font-weight: 800. Namun, dalam peluncuran fitur ini, kueri gaya saat ini hanya berfungsi dengan nilai properti kustom CSS. Ini masih sangat berguna untuk menggabungkan gaya dan memisahkan data dari desain. Mari kita lihat bagaimana Anda menggunakan kueri gaya dengan properti khusus CSS:

Memulai kueri gaya

Misalnya kita memiliki HTML berikut:

<ul class="card-list">
  <li class="card-container">
    <div class="card">
      ...
    </div>
  </li>
</ul>

Untuk menggunakan kueri gaya, Anda harus menyiapkan elemen penampung terlebih dahulu. Hal ini memerlukan pendekatan yang sedikit berbeda, bergantung pada apakah Anda mengkueri induk langsung atau tidak langsung.

Membuat kueri untuk orang tua langsung

Diagram kueri gaya.

Tidak seperti kueri gaya, Anda tidak perlu menerapkan pembatasan menggunakan properti container-type atau container ke .card-container agar .card dapat mengkueri gaya induk langsungnya. Namun, kita perlu menerapkan gaya (nilai properti kustom dalam kasus ini) ke penampung (dalam hal ini .card-container) atau elemen apa pun yang berisi elemen yang kita tata gayanya di DOM. Kita tidak dapat menerapkan gaya yang kita kuerikan pada elemen langsung yang kita tata gayanya menggunakan kueri tersebut karena hal ini dapat menyebabkan loop yang tidak terbatas.

Untuk langsung mengkueri induk, Anda dapat menulis:

/* styling .card based on the value of --theme on .card-container */
@container style(--theme: warm) {
  .card {
    background-color: wheat;
    border-color: brown; 
    ...
  }
}

Anda mungkin telah memperhatikan bahwa kueri gaya menggabungkan kueri dengan style(). Hal ini bertujuan untuk membedakan nilai ukuran dengan gaya. Misalnya, Anda dapat menulis kueri untuk lebar container sebagai @container (min-width: 200px) { … }. Ini akan menerapkan gaya jika lebar penampung induk setidaknya 200 px. Namun, min-width juga dapat menjadi properti CSS, dan Anda dapat mengajukan kueri untuk nilai CSS min-width menggunakan kueri gaya. Itulah sebabnya Anda menggunakan wrapper style() untuk memperjelas perbedaannya: @container style(min-width: 200px) { … }.

Menata gaya orang tua non-langsung

Jika ingin mengkueri gaya untuk elemen apa pun yang bukan merupakan induk langsung, Anda harus memberikan container-name pada elemen tersebut. Misalnya, kita dapat menerapkan gaya ke .card berdasarkan gaya .card-list dengan memberi .card-list container-name, dan mereferensikannya dalam kueri gaya.

/* styling .card based on the value of --moreGlobalVar on .card-list */
@container cards style(--moreGlobalVar: value) {
  .card {
    ...
  }
}

Umumnya, praktik terbaik adalah memberi nama penampung untuk memperjelas apa yang Anda kuerikan dan memungkinkan Anda mengakses penampung tersebut dengan lebih mudah. Salah satu contoh kegunaannya adalah jika Anda ingin menata gaya elemen dalam .card secara langsung. Tanpa penampung bernama di .card-container, pengguna tidak dapat mengkuerinya secara langsung.

Tetapi semua ini lebih masuk akal dalam praktiknya. Mari kita lihat beberapa contohnya:

Cara kerja kueri gaya

Gambar demo dengan beberapa kartu produk, beberapa dengan tag &#39;baru&#39; atau &#39;stok rendah&#39; dan kartu &#39;stok rendah&#39; dengan latar belakang merah.

Kueri gaya sangat berguna jika Anda memiliki komponen yang dapat digunakan kembali dengan beberapa variasi, atau ketika tidak memiliki kontrol atas semua gaya, tetapi perlu menerapkan perubahan dalam kasus tertentu. Contoh ini menunjukkan kumpulan kartu produk yang memiliki komponen kartu yang sama. Beberapa kartu produk memiliki detail/catatan tambahan seperti "Baru" atau "Stok Rendah", yang dipicu oleh properti khusus bernama --detail. Selain itu, jika produk berada dalam kategori "Stok Rendah", produk tersebut akan mendapatkan latar belakang batas merah yang gelap. Jenis informasi ini kemungkinan dirender oleh server, dan dapat diterapkan ke kartu melalui gaya inline seperti ini:

 <div class="product-list">
  <div class="product-card-container" style="--detail: new">
    <div class="product-card">
      <div class="media">
        <img .../>
      <div class="comment-block"></div>
    </div>
  </div>
  <div class="meta">
    ...
  </div>
  </div>
  <div class="product-card-container" style="--detail: low-stock">
    ...
  </div>
  <div class="product-card-container">
    ...
  </div>
  ...
</div>

Dengan data terstruktur ini, Anda dapat meneruskan nilai ke --detail, dan menggunakan properti kustom CSS ini untuk menerapkan gaya:

@container style(--detail: new) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'New';
    border: 1px solid currentColor;
    background: white;
    ...
  }
}

@container style(--detail: low-stock) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'Low Stock';
    border: 1px solid currentColor;
    background: white;
    ...
  }
  
  .media-img {
    border: 2px solid brickred;
  }
}

Kode di atas memungkinkan kita menerapkan chip untuk --detail: low-stock dan --detail: new, tetapi Anda mungkin melihat beberapa redundansi dalam blok kode. Saat ini, tidak ada cara untuk mengkueri keberadaan --detail dengan @container style(--detail) saja, yang akan memungkinkan pembagian gaya yang lebih baik dan lebih sedikit pengulangan. Kemampuan ini saat ini sedang dibahas dalam kelompok kerja.

Kartu cuaca

Contoh sebelumnya menggunakan satu properti kustom dengan beberapa kemungkinan nilai untuk menerapkan gaya. Tetapi Anda juga dapat mencampurnya dengan menggunakan dan membuat kueri untuk beberapa properti khusus. Ambil contoh kartu cuaca ini:

Demo kartu cuaca.

Untuk menata gaya gradien dan ikon latar belakang kartu ini, cari karakteristik cuaca, seperti “berawan”, “hujan”, atau “cerah”:

@container style(--sunny: true) {
  .weather-card {
    background: linear-gradient(-30deg, yellow, orange);
  }
  
  .weather-card:after {
    content: url(<data-uri-for-demo-brevity>);
    background: gold;
  }
}

Dengan cara ini, Anda dapat menata gaya setiap kartu berdasarkan karakteristik uniknya. Namun, Anda juga dapat menata gaya untuk kombinasi karakteristik (properti kustom), menggunakan kombinator and seperti halnya untuk kueri media. Misalnya, hari yang berawan dan cerah akan terlihat seperti ini:

@container style(--sunny: true) and style(--cloudy: true) {
    .weather-card {
      background: linear-gradient(24deg, pink, violet);
    }
  
  .weather-card:after {
      content: url(<data-uri-for-demo-brevity>);
      background: violet;
  }
}

Memisahkan data dari desain

Dalam kedua demo ini, ada manfaat struktural dari memisahkan lapisan data (DOM yang akan dirender di halaman) dari gaya yang diterapkan. Gaya ditulis sebagai varian yang mungkin ada dalam gaya komponen, sementara endpoint dapat mengirim data yang kemudian akan digunakan untuk menata gaya komponen. Anda dapat menggunakan satu nilai, seperti dalam kasus pertama, memperbarui nilai --detail, atau beberapa variabel, seperti dalam kasus kedua (menetapkan --rainy atau --cloudy atau --sunny. Bagian terbaiknya adalah Anda juga dapat menggabungkan nilai ini, dan memeriksa --sunny dan --cloudy dapat menampilkan gaya yang sebagian berawan.

Memperbarui nilai properti kustom melalui JavaScript dapat dilakukan dengan lancar, baik saat menyiapkan model DOM (yaitu saat membangun komponen dalam framework), atau memperbarui kapan saja menggunakan <parentElem>.style.setProperty('--myProperty’, <value>). I

Berikut adalah demo bahwa dalam beberapa baris kode, memperbarui --theme tombol, dan menerapkan gaya menggunakan kueri gaya dan properti khusus tersebut (--theme):

Sesuaikan gaya kartu menggunakan kueri gaya, JavaScript yang digunakan untuk memperbarui nilai properti kustom adalah:

const themePicker = document.querySelector('#theme-picker')
const btnParent = document.querySelector('.btn-section');

themePicker.addEventListener('input', (e) => {
  btnParent.style.setProperty('--theme', e.target.value);
})

Fitur yang dijelaskan dalam artikel ini hanyalah permulaan. Anda dapat mengharapkan lebih banyak hal dari kueri container untuk membantu Anda membangun antarmuka yang dinamis dan responsif. Khusus untuk kueri gaya, masih ada beberapa masalah yang belum terselesaikan. Salah satunya adalah implementasi kueri gaya untuk gaya CSS di luar properti kustom. Hal ini sudah menjadi bagian dari level spesifikasi saat ini, tetapi belum diterapkan di browser mana pun. Evaluasi konteks boolean diharapkan akan ditambahkan ke level spesifikasi saat ini saat masalah yang belum terselesaikan telah diselesaikan, sedangkan kueri rentang direncanakan untuk level spesifikasi berikutnya.