Menu navigasi jarang hanya satu level: di dalam item “Produk” sering masih ada submenu berisi tautan lain. Dengan descendant selector berbasis spasi, satu rule untuk li langsung mengenai item menu dan seluruh item submenu sekaligus — padahal sering kali yang ingin ditata hanyalah level pertamanya. Combinator child, ditulis dengan tanda lebih besar (>), menyelesaikan masalah ini: selector hanya mengenali anak langsung dan mengabaikan keturunan yang lebih dalam. Pada chapter ini kita mempelajari cara membacanya, membandingkannya dengan descendant selector pada struktur bersarang, dan melihat kapan sifat ketatnya justru menjaga stylesheet tetap rapi.

Combinator Child: Anak Langsung Saja #

Aturan dasarnya satu kalimat: selector di sebelah kiri > harus menjadi induk langsung dari selector di sebelah kanan.

css
nav > ul {
  border-top: 3px solid #14503a;
}

Cara membacanya: “pilih ul yang induknya persis nav” — ul yang bersarang lebih dalam di dalam li tidak termasuk.

Di balik layar, browser menguji satu hubungan saja untuk setiap kandidat: hubungan parent. Hubungan lebih jauh seperti grandparent tidak diperiksa. Inilah perbedaan mendasarnya dengan descendant selector, yang menelusuri seluruh kedalaman keturunan.

Child vs Descendant pada Menu Bersarang #

Perbedaan keduanya paling mudah terlihat pada menu yang punya submenu. Struktur HTML berikut akan kita pakai sepanjang chapter:

html
<nav class="menu-utama">
  <ul class="menu-level-1">
    <li>Beranda</li>
    <li>Produk
      <ul class="menu-level-2">
        <li>Kopi Gayo</li>
        <li>Kopi Toraja</li>
      </ul>
    </li>
    <li>Kontak</li>
  </ul>
</nav>

Sekarang kita pasang dua rule: satu berbasis descendant untuk gaya dasar semua item, satu berbasis child untuk level pertama saja:

css
.menu-utama li {
  padding: 10px 14px;
  list-style: none;
}

.menu-utama > ul > li {
  font-weight: 600;
  border-bottom: 2px solid #14503a;
}

Mari kita telaah kedua selector tersebut:

  1. .menu-utama li: combinator descendant. Browser memilih semua li di kedalaman berapa pun di dalam .menu-utama, karena itu item submenu ikut mendapat padding.
  2. .menu-utama > ul > li: rangkaian dua combinator child. Browser menuntut rantai yang persis: li harus anak langsung dari ul, dan ul tersebut harus anak langsung dari .menu-utama. Item submenu adalah anak dari li “Produk”, bukan dari ul level satu, sehingga tidak lolos seleksi.

Bayangkan bila rule kedua ditulis tanpa > menjadi .menu-utama ul li: garis bawah dan huruf tebal akan merambat ke Kopi Gayo dan Kopi Toraja, dan menu level satu kehilangan penanda visualnya. Satu karakter > di sini menentukan tampilan seluruh menu.

Demo berikut memasang kedua rule itu pada markup menu di atas:

Kapan Ketat Itu Membantu #

Combinator child paling berharga ketika struktur di dalam komponen sering berubah, tetapi hubungan tingkat pertamanya stabil. Beberapa pola yang umum:

KebutuhanSelectorMengapa cocok
Menata hanya menu level pertama.menu-utama > ul > lisubmenu tetap bebas dari gaya level satu
Judul kartu tidak memengaruhi heading di komponen dalam.kartu > h3heading milik widget lain di dalam kartu tidak ikut
Item galeri tingkat atas saja.galeri > imggambar yang nanti dibungkus figure tidak ikut bergaya

Sifat ketat ini juga membuat stylesheet lebih tahan terhadap perubahan markup yang dalam. Bila besok submenu diperdalam satu level lagi atau isi kartu dirombak, rule berbasis child tetap menempel pada hubungan yang sama, sehingga gayanya tidak tiba-tiba menyebar ke tempat yang tidak kita maksud.

Kesalahan Umum #

KesalahanAkibatPerbaikan
Membaca selector terbalik, misalnya li > .menu padahal yang dimaksud .menu > liTidak ada elemen yang cocok, gaya tidak munculIngat arah baca: induk di kiri, anak di kanan
Mengira > memilih semua keturunanGaya “tidak turun” ke submenu dan terasa tidak berfungsiGanti satu > menjadi spasi bila memang ingin semua level
Menyusun jalur terlalu dalam, misalnya nav > div > ul > li > aSpecificity membengkak dan selector rapuh saat markup berubahJaga jalur pendek, tempelkan class pada titik yang stabil

Ringkasan #

Combinator child (>) membatasi seleksi hanya pada anak langsung, berlawanan dengan descendant selector yang menjangkau seluruh keturunan. Keduanya sering dipakai bersama: descendant untuk gaya dasar yang berlaku di semua level, child untuk aksen yang hanya milik level pertama. Berikutnya kita berpindah dari hubungan vertikal induk-anak ke hubungan mendatar: menata gaya elemen berdasarkan tetangganya dengan sibling selector.