Kemampuan untuk mengkueri ukuran inline induk, dan nilai unit kueri penampung baru-baru ini mendapatkan dukungan stabil di semua mesin browser modern.
Namun, spesifikasi penahanan menyertakan lebih dari sekadar kueri ukuran; hal ini juga memungkinkan kueri nilai gaya induk. Mulai Chromium 111, Anda dapat menerapkan pembatasan gaya untuk nilai properti khusus dan mengkueri elemen induk untuk nilai properti kustom.
Ini berarti kita memiliki kontrol gaya yang lebih logis lagi dalam CSS, dan memungkinkan pemisahan yang lebih baik antara logika aplikasi dan lapisan data dari gayanya.
Spesifikasi Modul Penahanan CSS Level 3, yang mencakup kueri ukuran dan gaya, memungkinkan semua 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 khusus 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 membuat kueri induk langsung atau tidak langsung.
Membuat kueri induk langsung
Tidak seperti kueri gaya, Anda tidak perlu menerapkan containment 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 hal 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 diminta 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 melihat bahwa kueri gaya menggabungkan kueri dengan style()
. Ini untuk membedakan nilai ukuran dari gaya. Misalnya, Anda dapat menulis kueri untuk lebar penampung sebagai @container (min-width: 200px) { … }
. Ini akan menerapkan gaya jika penampung induk memiliki lebar setidaknya 200 piksel. Namun, min-width
juga dapat berupa properti CSS, dan Anda dapat membuat kueri untuk nilai CSS min-width
menggunakan kueri gaya. Itulah sebabnya Anda harus menggunakan wrapper style()
untuk memperjelas perbedaannya: @container style(min-width: 200px) { … }
.
Menata gaya induk tidak langsung
Jika ingin mengkueri gaya untuk elemen apa pun yang bukan induk langsung, Anda harus memberikan container-name
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 memberikan nama penampung untuk memperjelas apa yang Anda minta dan mendapatkan kemampuan untuk 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
, penampung tidak dapat mengkuerinya secara langsung.
Tapi semua ini lebih masuk akal dalam praktiknya. Mari kita lihat beberapa contohnya:
Cara kerja kueri gaya
Kueri gaya sangat berguna ketika Anda memiliki komponen yang dapat digunakan kembali dengan beberapa variasi, atau bila Anda tidak memiliki kontrol atas semua gaya tetapi perlu menerapkan perubahan dalam kasus tertentu. Contoh ini menunjukkan kumpulan kartu produk yang menggunakan komponen kartu yang sama. Beberapa kartu produk memiliki detail/catatan tambahan seperti "Baru" atau "Stok Rendah", yang dipicu oleh properti kustom bernama --detail
. Selain itu, jika produk berada di “Stok Rendah”, produk akan mendapatkan latar belakang batas merah yang mendalam. Jenis informasi ini kemungkinan dirender oleh server, dan dapat diterapkan ke kartu melalui gaya inline seperti berikut:
<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 telah melihat beberapa redundansi dalam blok kode. Saat ini, tidak ada cara untuk mengkueri hanya kehadiran --detail
dengan @container style(--detail)
, yang memungkinkan pembagian gaya yang lebih baik dan lebih sedikit pengulangan. Kemampuan ini sedang didiskusikan dalam grup kerja.
Kartu cuaca
Contoh sebelumnya menggunakan satu properti khusus dengan beberapa kemungkinan nilai untuk menerapkan gaya. Tetapi Anda juga dapat mencampurnya dengan menggunakan dan membuat kueri untuk beberapa properti kustom. Ambil contoh kartu cuaca ini:
Untuk menata gaya gradien latar belakang dan ikon untuk 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
dengan cara yang sama seperti untuk kueri media. Misalnya, hari yang berawan dan cerah akan terlihat seperti:
@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 pada halaman) dari gaya yang diterapkan. Gaya ditulis sebagai kemungkinan varian yang aktif dalam gaya komponen, sedangkan 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
. Dan bagian terbaiknya adalah Anda juga dapat menggabungkan nilai-nilai ini, memeriksa --sunny
dan --cloudy
dapat menampilkan gaya sebagian berawan.
Memperbarui nilai properti kustom melalui JavaScript dapat dilakukan dengan lancar, baik saat menyiapkan model DOM (yaitu saat membuat komponen dalam framework), maupun memperbaruinya 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
):
Menata 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 mem-build antarmuka yang dinamis dan responsif. Khusus untuk kueri gaya, masih ada beberapa masalah yang belum diselesaikan. Salah satunya adalah implementasi kueri gaya untuk gaya CSS di luar properti khusus. Ini sudah menjadi bagian dari tingkat spesifikasi saat ini, tetapi belum diterapkan di browser apa pun. Evaluasi konteks boolean diharapkan akan ditambahkan ke tingkat spesifikasi saat ini ketika masalah yang belum terselesaikan telah diselesaikan, sementara pembuatan kueri rentang direncanakan untuk tingkat spesifikasi berikutnya.