Banyak masalah styling yang sebenarnya soal posisi: daftar menu perlu sudut melengkung hanya di ujungnya, item pertama tidak butuh jarak atas, dan kartu notifikasi yang kosong sebaiknya tidak terlihat sama sekali. Pseudo-class struktural menyelesaikan semuanya dengan mencocokkan elemen berdasarkan posisinya di antara saudara-saudaranya, tanpa class tambahan di HTML. Pada chapter ini kita mengenal :first-child, :last-child, :only-child, dan :empty, lalu menerapkannya pada daftar yang benar-benar sering muncul di proyek nyata.
Mencocokkan Berdasarkan Posisi Saudara #
Ketiga pseudo-class pertama bekerja pada hubungan antarelemen di dalam induk yang sama:
| Pseudo-class | Cocok ketika |
|---|---|
:first-child | elemen adalah anak pertama dari induknya |
:last-child | elemen adalah anak terakhir dari induknya |
:only-child | elemen adalah satu-satunya anak — sekaligus anak pertama dan terakhir |
Yang dihitung hanyalah elemen, bukan text node: spasi, baris baru, dan indentasi di antara tag tidak menghalangi pencocokan. Dengan begitu, markup yang rapi dan berindentasi tetap bisa ditarget dengan aman.
.menu-versi li:first-child {
font-weight: 700;
}
.menu-versi li:last-child {
border-bottom: none;
}Daftar riwayat versi berikut menunjukkan keduanya — item pertama tampil tebal, item terakhir kehilangan garis bawahnya:
Sudut Melengkung pada Ujung Daftar #
Kasus klasik: sebuah grup diberi border dan sudut melengkung, lalu tiap item diberi latar. Tanpa bantuan tambahan, latar item pertama dan terakhir berbentuk persegi dan menutupi sudut melengkung induknya. Solusinya melekatkan radius pada item ujung:
.daftar-menu {
list-style: none;
margin: 0;
padding: 0;
border: 1px solid #9ed2b5;
border-radius: 12px;
}
.daftar-menu li {
padding: 10px 14px;
background-color: #f4fbf7;
}
.daftar-menu li + li {
border-top: 1px solid #9ed2b5;
}
.daftar-menu li:first-child {
border-radius: 11px 11px 0 0;
}
.daftar-menu li:last-child {
border-radius: 0 0 11px 11px;
}Demo berikut memakai persis aturan di atas pada daftar harga kopi:
Mari kita telaah dua aturan terakhirnya:
li:first-child: hanya item paling atas yang mendapat radius pada sudut kiri-atas dan kanan-atas.li:last-child: hanya item paling bawah yang mendapat radius pada sudut kiri-bawah dan kanan-bawah; item di tengah tidak tersentuh.
:only-child melengkapi resep ini dengan rapi: bila daftar hanya berisi satu item, item itu sekaligus anak pertama dan terakhir, namun dua aturan di atas tidak memberinya radius bawah dan atas sekaligus. Tambahkan satu aturan khusus:
.daftar-menu li:only-child {
border-radius: 11px;
}Menyembunyikan Container Kosong dengan :empty #
Pseudo-class :empty mencocokkan elemen yang tidak memiliki anak sama sekali. Pola yang paling sering dipakai adalah menyembunyikan wadah notifikasi yang belum berisi pesan:
.kotak-notifikasi:empty {
display: none;
}Menariknya, komentar HTML tidak menghalangi pencocokan — <div><!-- menunggu pesan --></div> tetap dianggap kosong.
Lihat perbedaannya pada dua wadah berikut — aturan :empty yang sama menyembunyikan yang kosong dan membiarkan yang berisi:
Kesalahan Umum #
| Kesalahan | Akibatnya | Perbaikannya |
|---|---|---|
Mengira :first-child mencocokkan elemen pertama dari sebuah class | selector tidak mencocokkan apa pun karena yang dihitung adalah posisi anak, bukan class | gunakan :nth-child(1 of .class) untuk menghitung berdasarkan class |
| Menerapkan aturan pada anak yang induknya berbeda-beda | gaya ujung daftar tidak muncul di beberapa grup | pastikan seleksi menempel pada induk yang sama dengan struktur HTML |
Mengandalkan whitespace agar :empty cocok | wadah tetap tampil karena spasi dianggap isi | tulis wadah benar-benar kosong di antara tag |
Ringkasan #
Pseudo-class struktural mencocokkan elemen berdasarkan posisinya: :first-child dan :last-child mengunci kedua ujung, :only-child menangani kasus tunggal, dan :empty menyembunyikan wadah tanpa isi. Kombinasi keduanya menyelesaikan pola daftar yang muncul di hampir setiap proyek. Chapter berikutnya memperluas ide posisi ini menjadi aritmetika: :nth-child() yang bisa menyasar baris genap, kelipatan tiga, bahkan tiga teratas.