Sampai chapter ini, setiap selector yang kita tulis berdiri sendiri: satu pola, satu kelompok target. Descendant selector menambah dimensi baru — sebuah spasi di antara dua selector — sehingga kita dapat menyasar elemen berdasarkan posisinya di dalam elemen lain: paragraf di dalam kartu, link di dalam navigasi, judul di dalam artikel. Dengan satu kombinasi ini, aturan yang luas dari element selector bisa dibatasi hanya pada area tertentu, tanpa menambah satu class pun.
Spasi yang Berarti “di Dalam” #
.kartu p {
line-height: 1.7;
}Spasi di antara .kartu dan p disebut kombinator descendant. Cara membacanya dari kanan ke kiri: pilih semua elemen p yang memiliki leluhur ber-class kartu. Diagram berikut menandai elemen mana yang cocok:
<div class="kartu"> ← leluhur yang dicari
<p>...</p> ← cocok: turunan langsung
<div class="isi">
<p>...</p> ← cocok juga: turunan tidak langsung
</div>
</div>
<p>...</p> ← di luar .kartu: tidak cocokDemo berikut menampilkan tiga paragraf dengan tag yang sama; dua di antaranya berada di dalam kartu, satu di luar:
Selector .kartu mengatur wadahnya, sedangkan .kartu p mengatur isinya; keduanya dapat dibaca dan diubah terpisah.
Kedalaman bukan soal: p yang bersarang dua, tiga, atau lebih tingkat tetap cocok selama ada .kartu di rantai leluhurnya. Sebaliknya, elemen p di luar kartu sama sekali tidak tersentuh aturan tersebut.
Rantainya pun boleh lebih dari dua bagian, misalnya .sidebar .menu a: setiap bagian tambahan mempersempit hasil, sekaligus menaikkan bobot aturan. Alasan inilah yang menjaga kita tetap menulis rantai sesingkat mungkin — prinsip yang dirinci di bagian akhir chapter.
Styling Kontekstual #
Kombinasi ini menyelesaikan dilema dari chapter Element Selector: kita ingin aturan yang luas, tetapi hanya pada area tertentu. Solusinya menggabungkan keduanya — element selector sebagai target, class area sebagai pembatas:
nav a {
text-decoration: none;
color: #1f2933;
}
.artikel p {
line-height: 1.8;
max-width: 65ch;
}Demo berikut menyandingkan link di dalam dan di luar nav, disertai satu paragraf artikel:
Perhatikan bahwa markup tidak memerlukan class tambahan: nav a menyasar semua link dalam navigasi sekaligus, dan .artikel p mengatur ritme baca seluruh artikel. Dua aturan semacam ini mencakup puluhan elemen tanpa satu atribut styling pun pada HTML.
Bagian kiri kombinator bisa berupa selector apa pun yang sudah kita kenal: element, class, bahkan attribute selector. Pola .kartu .tombol-utama mengubah gaya tombol utama hanya saat ia berada di dalam kartu, dan .footer a[href^="https"] menyasar link keluar khusus di area footer. Konteks ikut membawa makna: elemen yang sama dapat tampil berbeda sesuai asalnya, tanpa mengubah markup sama sekali.
Menjaga Selector Tetap Ringkas #
Kekuatan descendant selector ada pada keseimbangannya — cukup panjang untuk presisi, cukup pendek untuk terbaca. Beberapa kebiasaan yang menjaga keseimbangan itu:
- Batasi kedalaman:
.kartu plebih mudah dibaca daripada.halaman .utama .kartu div p, meskipun keduanya cocok dengan elemen yang sama. - Tidak perlu meniru seluruh struktur DOM: sertakan hanya rantai leluhur yang benar-benar membedakan target.
- Ingat bahwa target sebenarnya adalah selector paling kanan; bagian di depannya hanya konteks.
- Setiap bagian menambah bobot specificity — rantai panjang membuat penimpaan makin sulit, sebagaimana dibahas pada section Cascade, Inheritance, dan Specificity.
Kesalahan Umum #
| Kesalahan | Akibat | Perbaikan |
|---|---|---|
Meniru seluruh jalur DOM (.sidebar nav ul li a) | Selector panjang, sulit dijaga, bobot specificity membengkak | Singkat ke bagian yang membedakan: .sidebar a |
| Mengira spasi berarti anak langsung | Elemen bersarang jauh ikut terpilih, kadang tanpa disengaja | Gunakan kombinator anak (>) yang lebih ketat — dibahas segera setelah ini |
Lupa menulis spasi (div.kartu saat maksudnya div .kartu) | Makna berubah total: satu div ber-class kartu, bukan kartu di dalam div | Periksa jarak antarbagian selector sebelum menyimpan berkas |
Ringkasan #
Descendant selector menghubungkan dua selector dengan spasi dan menyasar elemen apa pun yang berada di dalam elemen lain, sedalam apa pun. Ia menjembatani aturan luas dan area terbatas: element selector untuk target, class untuk konteks. Setelah ini kita mengenal kombinator yang membatasi hubungan lebih ketat — anak langsung dan elemen saudara — sehingga presisi seleksi kita makin lengkap.