Salah satu fitur praprosesor CSS favorit kami kini terintegrasi dalam bahasa: aturan gaya bertingkat.
Sebelum pembuatan bertingkat, setiap pemilih harus dideklarasikan secara eksplisit, secara terpisah satu sama lain. Hal ini menyebabkan pengulangan, stylesheet yang massal, dan pengalaman penulisan yang tersebar.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Setelah penyusunan, pemilih dapat dilanjutkan dan aturan gaya yang terkait dengannya dapat dikelompokkan di dalamnya.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Penyusunan bertingkat membantu developer mengurangi kebutuhan pemilih berulang sekaligus
menentukan aturan gaya untuk elemen terkait. Hal ini juga dapat membantu gaya mencocokkan
HTML yang mereka targetkan. Jika komponen .nesting
dalam contoh sebelumnya
dihapus dari project, Anda dapat menghapus seluruh grup, bukan menelusuri
file untuk instance pemilih terkait.
Nesting dapat membantu dengan: - Organisasi - Mengurangi ukuran file - Pemfaktoran ulang
Nesting tersedia mulai Chrome 112 dan juga dapat dicoba di Safari Technical Preview 162.
Memulai CSS Nesting
Sepanjang sisa postingan ini,sandbox demo berikut digunakan untuk membantu Anda memvisualisasikan pilihan. Dalam status default ini, tidak ada yang dipilih dan semuanya terlihat. Dengan memilih berbagai bentuk dan ukuran, Anda dapat berlatih sintaksis dan melihat cara kerjanya.
Di dalam sandbox terdapat lingkaran, segitiga, dan persegi. Ada yang kecil, sedang,
atau besar. Warna lainnya berwarna biru, merah muda, atau ungu. Semuanya berada di dalam elemen
yang memuat .demo
. Berikut adalah pratinjau elemen HTML yang akan Anda
targetkan.
<div class="demo">
<div class="sm triangle pink"></div>
<div class="sm triangle blue"></div>
<div class="square blue"></div>
<div class="sm square pink"></div>
<div class="sm square blue"></div>
<div class="circle pink"></div>
…
</div>
Contoh bertingkat
Dengan bertingkat CSS, Anda dapat menentukan gaya untuk elemen dalam konteks pemilih lain.
.parent {
color: blue;
.child {
color: red;
}
}
Dalam contoh ini, pemilih class .child
disusun bertingkat dalam
pemilih class .parent
. Artinya, pemilih .child
bertingkat hanya akan
diterapkan pada elemen yang merupakan turunan dari elemen dengan class .parent
.
Contoh ini dapat juga ditulis menggunakan simbol &
, untuk menunjukkan secara eksplisit
lokasi penempatan class induk.
.parent {
color: blue;
& .child {
color: red;
}
}
Kedua contoh tersebut secara fungsional setara dan alasan Anda memiliki beberapa opsi akan menjadi lebih jelas ketika contoh lanjutan lainnya dibahas dalam artikel ini.
Memilih lingkaran
Untuk contoh pertama ini, tugasnya adalah menambahkan gaya untuk memudar dan memburamkan lingkaran di dalam demo saja.
Tanpa penyusunan bertingkat, CSS saat ini:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Dengan penyusunan bertingkat, ada dua cara yang valid:
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
atau
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
Hasilnya, semua elemen di dalam .demo
dengan class .circle
menjadi buram dan hampir tidak terlihat:
Memilih segitiga dan persegi
Tugas ini mengharuskan pemilihan beberapa elemen bertingkat, juga disebut pemilih grup.
Tanpa penyusunan bertingkat, CSS saat ini memiliki dua cara:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
atau, menggunakan :is()
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Dengan penyusunan bertingkat, berikut adalah dua cara yang valid:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
atau
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Hasilnya, hanya elemen .circle
yang tetap berada di dalam .demo
:
Memilih segitiga dan lingkaran besar
Tugas ini memerlukan pemilih gabungan, dengan elemen harus memiliki kedua class agar dapat dipilih.
Tanpa penyusunan bertingkat, CSS saat ini:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
atau
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Dengan penyusunan bertingkat, berikut adalah dua cara yang valid:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
atau
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Hasilnya, semua segitiga dan lingkaran besar disembunyikan di dalam .demo
:
Tips pro dengan pemilih gabungan dan bertingkat
Simbol &
adalah teman Anda di sini karena menunjukkan secara eksplisit cara menggabungkan pemilih
bertingkat. Perhatikan contoh berikut:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Meskipun merupakan cara yang valid untuk menyusun bertingkat, hasilnya tidak akan cocok dengan elemen yang Anda harapkan.
Alasannya adalah tanpa &
untuk menentukan hasil gabungan .lg.triangle,
.lg.circle
yang diinginkan, hasil sebenarnya adalah .lg .triangle, .lg
.circle
; pemilih turunan.
Memilih semua bentuk kecuali yang berwarna merah muda
Tugas ini memerlukan class pseudo fungsional negasi, dengan elemen tidak boleh memiliki pemilih yang ditentukan.
Tanpa penyusunan bertingkat, CSS saat ini:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Dengan penyusunan bertingkat, berikut adalah dua cara yang valid:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
atau
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
Hasilnya, semua bentuk yang tidak berwarna merah muda disembunyikan di dalam .demo
:
Presisi dan fleksibilitas dengan &
Misalnya Anda ingin menargetkan .demo
dengan pemilih :not()
. &
diperlukan untuk
hal tersebut:
.demo {
&:not() {
...
}
}
Tindakan ini menggabungkan .demo
dan :not()
menjadi .demo:not()
, berbeda dengan contoh sebelumnya
yang memerlukan .demo :not()
. Pengingat ini sangat penting saat
ingin menyusun bertingkat interaksi :hover
.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Contoh penyusunan bertingkat lainnya
Spesifikasi CSS untuk pembuatan bertingkat dilengkapi dengan lebih banyak contoh. Jika Anda ingin mempelajari sintaksisnya lebih lanjut melalui contoh, panduan ini mencakup berbagai contoh yang valid dan tidak valid.
Beberapa contoh berikutnya akan secara singkat memperkenalkan fitur pembuatan bertingkat CSS, untuk membantu Anda memahami luasnya kemampuan yang diperkenalkannya.
Menyusun @media
Berpindah ke area stylesheet yang berbeda bisa sangat mengganggu untuk menemukan kondisi kueri media yang memodifikasi pemilih dan gayanya. Gangguan itu hilang dengan kemampuan untuk menyarangkan kondisi tepat di dalam konteks.
Untuk kemudahan sintaksis, jika kueri media bertingkat hanya mengubah gaya untuk konteks pemilih saat ini, sintaksis minimal dapat digunakan.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
Penggunaan &
secara eksplisit juga dapat digunakan:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
Contoh ini menunjukkan sintaksis yang diperluas dengan &
, sekaligus menargetkan kartu
.large
untuk menunjukkan fitur bertingkat tambahan yang terus berfungsi.
Pelajari lebih lanjut cara membuat @rules lebih lanjut.
Bertingkat di mana saja
Semua contoh sampai saat ini adalah lanjutan atau ditambahkan ke konteks sebelumnya. Anda dapat sepenuhnya mengubah atau mengatur ulang konteksnya jika diperlukan.
.card {
.featured & {
/* .featured .card */
}
}
Simbol &
merepresentasikan referensi ke objek pemilih (bukan string) dan
dapat ditempatkan di mana saja dalam pemilih bertingkat. Bahkan dapat ditempatkan beberapa kali:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Meskipun contoh ini sedikit tidak berguna, tentu ada skenario ketika kemampuan untuk mengulangi konteks pemilih juga berguna.
Contoh penyusunan bertingkat tidak valid
Ada beberapa skenario sintaksis bertingkat yang tidak valid dan mungkin mengejutkan Anda jika selama ini Anda menggunakan praprosesor.
Penyusunan dan penyambungan
Banyak konvensi penamaan class CSS bergantung pada kemampuan penyusunan bertingkat untuk menggabungkan atau menambahkan pemilih seolah-olah mereka adalah string. Hal ini tidak berfungsi dalam penyusunan bertingkat CSS karena pemilih bukan string, melainkan referensi objek.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Penjelasan yang lebih mendalam dapat ditemukan di spesifikasi.
Contoh penyusunan bertingkat yang rumit
Bertingkat dalam daftar pemilih dan :is()
Pertimbangkan blok CSS bertingkat berikut:
.one, #two {
.three {
/* some styles */
}
}
Ini adalah contoh pertama yang dimulai dengan daftar pemilih, lalu terus disusun bertingkat. Contoh sebelumnya hanya berakhir dengan daftar pemilih. Tidak ada yang tidak valid dalam contoh penyusunan bertingkat ini, tetapi ada detail implementasi yang berpotensi rumit tentang penyusunan bertingkat di dalam daftar pemilih, terutama yang menyertakan pemilih ID.
Agar intent penyusunan bertingkat berfungsi, setiap daftar pemilih yang bukan bagian bertingkat paling dalam, akan digabungkan dengan :is()
oleh browser. Pembungkus ini mempertahankan pengelompokan daftar pemilih dalam konteks yang ditulis. Efek samping pengelompokan ini, :is(.one, #two)
, adalah bahwa pengelompokan ini mengadopsi kekhususan skor tertinggi dalam pemilih dalam tanda kurung. Inilah cara :is()
selalu bekerja, tetapi mungkin akan mengejutkan saat menggunakan sintaksis bertingkat karena itu tidak persis seperti yang ditulis. Ringkas triknya; menyusun bertingkat dengan ID dan daftar pemilih dapat menyebabkan pemilih kekhususan yang sangat tinggi.
Untuk meringkas contoh rumit dengan jelas, blok bertingkat sebelumnya akan diterapkan ke dokumen sebagai berikut:
:is(.one, #two) .three {
/* some styles */
}
Waspadalah atau ajari linter Anda untuk memperingatkan saat membuat bertingkat di dalam daftar pemilih yang menggunakan pemilih ID, kekhususan semua tingkatan dalam daftar pemilih tersebut akan tinggi.
Menggabungkan penyusunan bertingkat dan deklarasi
Pertimbangkan blok CSS bertingkat berikut:
.card {
color: green;
& { color: blue; }
color: red;
}
Warna elemen .card
akan menjadi blue
.
Setiap deklarasi gaya yang dicampur akan diangkat ke atas, seolah-olah sudah ditulis sebelum terjadi bertingkat. Detail selengkapnya dapat ditemukan di spesifikasi.
Ada cara untuk melakukannya. Kode berikut menggabungkan tiga gaya warna dalam &
, yang
mempertahankan urutan menurun seperti yang mungkin dimaksudkan penulis. Warna elemen
.card
akan menjadi merah.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Bahkan, sebaiknya gabungkan semua gaya yang mengikuti penyusunan bertingkat dengan &
.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Deteksi fitur
Ada dua cara efektif untuk mendeteksi penyusunan bertingkat CSS: menggunakan pembuatan bertingkat atau gunakan
@supports
untuk memeriksa kemampuan penguraian pemilih bertingkat.
Menggunakan penyusunan bertingkat:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
Menggunakan @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
Kolega saya, Bramus, memiliki Codepen yang hebat yang menunjukkan strategi ini.
Proses debug dengan Chrome DevTools
Dukungan saat ini di DevTools untuk pembuatan bertingkat minimal. Saat ini, Anda akan menemukan gaya ditampilkan di panel Styles seperti yang diharapkan, tetapi pelacakan tingkatan dan konteks pemilih lengkapnya belum didukung. Kami memiliki desain dan rencana untuk membuat ini transparan dan jelas.
Chrome 113 berencana menyediakan dukungan tambahan untuk pembuatan bertingkat CSS. Terus ikuti perkembangannya.
Acara mendatang
CSS Nesting hanya tersedia di versi 1. Versi 2 akan memperkenalkan lebih banyak sugar sintaksis dan kemungkinan lebih sedikit aturan untuk dihafal. Ada banyak permintaan untuk penguraian bertingkat agar tidak dibatasi atau mengalami momen yang rumit.
Peningkatan adalah peningkatan besar pada bahasa CSS. Hal ini memiliki implikasi penulisan ke hampir setiap aspek arsitektur CSS. Dampak besar ini perlu dieksplorasi dan dipahami secara mendalam sebelum versi 2 dapat ditentukan secara efektif.
Sebagai pengingat terakhir, berikut demo
yang menggunakan @scope
, pembuatan bertingkat, dan @layer
secara bersamaan. Semuanya sangat menarik!