Stylesheet yang tumbuh seiring proyek sering memuat selector panjang seperti .kartu .judul dan .kartu .judul .ikon yang mengulang nama induknya berulang-ulang. Nesting bawaan CSS — fitur yang merupakan Baseline sejak 2023 (Chrome 120, Firefox 117, Safari 17.2) — memungkinkan kita menulis aturan anak di dalam blok aturan induknya, sehingga relasi antar-elemen terlihat langsung dari struktur kode. Kini kita tidak memerlukan preprocessor seperti Sass untuk mendapatkan kemampuan ini; browser modern membacanya sebagai CSS murni. Pada Chapter ini kita menulis aturan tersarang pertama, memakai tanda & untuk konteks eksplisit, dan menilai kapan nesting justru mengaburkan kode.

Aturan Anak di Dalam Aturan Induk #

Bentuk paling dasar nesting adalah memindahkan selector turunan ke dalam blok induk. Bandingkan penulisan klasik berikut:

css
/* Tanpa nesting: selector induk ditulis berulang */
.kartu { color: rgb(51, 65, 85); }
.kartu .judul { color: rgb(14, 165, 233); }

/* Dengan nesting: satu blok mencakup semuanya */
.kartu {
  color: rgb(51, 65, 85);

  .judul { color: rgb(14, 165, 233); }
}

Kedua versi menghasilkan aturan yang identik bagi browser: .kartu berwarna abu-abu gelap, dan .judul di dalam .kartu berwarna biru. Nesting hanya mengubah cara menulis, bukan cara browser mencocokkan selector — hasil “kompilasi” konseptualnya tetap selector turunan biasa. Mari kita telaah versi tersarangnya:

  1. Baris 6 (.kartu {): aturan induk dibuka seperti biasa, berisi deklarasi color untuk kartu itu sendiri.
  2. Baris 8 (.judul { ... }): aturan bersarang berada di dalam blok induk. Browser menambahkan selector induk di depannya, sehingga aturan ini menjadi .kartu .judul.
  3. Deklarasi dan aturan anak boleh berdampingan: urutan penulisannya bebas, tetapi menaruh deklarasi lebih dulu lalu aturan anak menjaga kode tetap terbaca.

Tanda & untuk Konteks Eksplisit #

Tanda nesting selector & menunjuk ke aturan induk secara eksplisit. Dengan & kita dapat menulis varian compound, pseudo-class, dan pseudo-element tanpa mengulang nama induk. Contoh lengkap pada demo chapter ini memakai pola berikut:

.kartu {
  padding: 16px;
  border: 1px solid rgb(203, 213, 225);
  border-radius: 12px;
  background-color: rgb(255, 255, 255);
  color: rgb(51, 65, 85);

  & .judul {
    color: rgb(14, 165, 233);
    font-weight: 700;
  }

  &.unggulan {
    background-color: rgb(240, 249, 255);
    border-color: rgb(14, 165, 233);
  }

  &:hover {
    border-color: rgb(2, 132, 199);
  }
}

Empat pola bekerja di file tersebut:

  1. & .judul: keturunan dari kartu — setara dengan .kartu .judul.
  2. &.unggulan: tanpa spasi setelah &, sehingga menjadi compound — setara dengan .kartu.unggulan, kartu yang sekaligus membawa class unggulan.
  3. &:hover: pseudo-class pada induk itu sendiri — setara dengan .kartu:hover, aktif ketika kursor berada di atas kartu.
  4. Spasi vs tanpa spasi: & .judul dan &.unggulan berbeda makna persis seperti .kartu .judul dan .kartu.unggulan pada selector klasik.

Pseudo-class interaktif seperti :hover tidak dapat diperiksa oleh harness otomatis; perilakunya kita uji manual dengan mengarahkan kursor ke kartu pada demo.

Menjaga Nesting Tetap Terbaca #

Nesting yang terlalu dalam mereplikasi masalah yang dulu ditimpa preprocessor: blok bersarang empat tingkat menyembunyikan selector final dan menyulitkan pencarian. Batasi kedalaman dua hingga tiga tingkat, dan pindahkan komponen berbeda ke aturan induknya sendiri. Nesting paling berguna untuk keadaan lokal satu komponen — varian, judul internal, dan pseudo-class miliknya — bukan untuk memetakan seluruh halaman.

Karena fitur ini merupakan Baseline sejak 2023, seluruh browser utama telah membacanya; untuk browser lama di luar rentang tersebut, sediakan stylesheet fallback yang menulis selector secara datar. Rujukan lengkapnya ada pada CSS nesting di MDN .

Demo: Kartu dengan Aturan Tersarang #

html index.html
<div class="kartu" data-expected='{"color":"rgb(51, 65, 85)","border-color":"rgb(203, 213, 225)"}'>
  <p class="judul" data-expected='{"color":"rgb(14, 165, 233)","font-weight":"700"}'>Laporan Bulanan</p>
  <p>Ringkasan aktivitas proyek bulan ini.</p>
</div>
<div class="kartu unggulan" data-expected='{"background-color":"rgb(240, 249, 255)","border-color":"rgb(14, 165, 233)"}'>
  <p class="judul">Laporan Unggulan</p>
</div>

Hasil di Browser:

text
Kartu pertama tampil dengan teks abu-abu gelap (color: rgb(51, 65, 85))
dan garis abu-abu (border-color: rgb(203, 213, 225)).
Judul di dalam kartu tampil biru dan tebal — color: rgb(14, 165, 233),
font-weight: 700 — hasil aturan & .judul yang tersarang.
Kartu kedua membawa class unggulan sehingga berlatar biru muda
(background-color: rgb(240, 249, 255)) bergaris biru
(border-color: rgb(14, 165, 233)) lewat aturan &.unggulan.
Ketika kursor diarahkan ke kartu mana pun, garisnya berubah biru tua
— hasil aturan &:hover yang diverifikasi manual pada demo.

Demo lengkap membawa atribut data-expected pada kartu dan judul, memverifikasi warna pemenang dari aturan tersarang statis secara otomatis.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh-kartu-nesting.css

Unduh berkas
css
.kartu {
  padding: 16px;
  border: 1px solid rgb(203, 213, 225);
  border-radius: 12px;
  background-color: rgb(255, 255, 255);
  color: rgb(51, 65, 85);

  & .judul {
    color: rgb(14, 165, 233);
    font-weight: 700;
  }

  &.unggulan {
    background-color: rgb(240, 249, 255);
    border-color: rgb(14, 165, 233);
  }

  &:hover {
    border-color: rgb(2, 132, 199);
  }
}