Kadang daftar elemen yang ingin ditata jauh lebih mudah dijelaskan dari kebalikannya: semua item kecuali yang terakhir, semua tautan kecuali yang sedang aktif, semua chip kecuali dua varian utama. Menulis selector untuk pengecualian seperti ini satu per satu melelahkan dan cepat usang. Pseudo-class :not() membalik logikanya: kita menyebut pola yang tidak ingin dicocokkan, dan sisanya otomatis masuk. Pada chapter ini kita mempelajari cara kerjanya, argumen berupa daftar selector, serta dampaknya pada specificity.

Membalik Pencocokan #

:not(X) mencocokkan elemen yang tidak memenuhi selector X. Pseudo-class ini menempel pada selector seperti pseudo-class lain, dan argumennya boleh berupa selector apa pun — termasuk pseudo-class lain:

css
.daftar-nav li:not(:last-child) {
  border-right: 1px solid #d1d9d6;
}

Tanpa :not(), kita harus memberi class khusus pada item terakhir dan mengingatnya setiap kali daftar berubah.

Pola ini juga merapikan jarak antaritem tanpa gap: beri margin-bottom pada semua item kecuali terakhir, dan daftar berapapun panjangnya tetap rapi di ujung bawah.

Argumen Berupa Daftar Selector #

Selector lama hanya menerima satu argumen sederhana; CSS modern menerima daftar. Kini kita bisa menulis :not(h1, h2) tanpa merangkai beberapa :not():

css
.chip:not(.utama, .sekunder) {
  border: 1px dashed #9aa8a1;
  color: #52605a;
}

Bentuk lama yang setara — :not(.utama):not(.sekunder) — masih sah, tetapi bentuk daftar lebih ringkas dan mudah dibaca.

Perhatikan dua chip terakhir pada demo berikut yang jatuh ke aturan pengecualian:

Kombinasi dengan state juga lazim dipakai untuk menu:

css
.menu-nav a:not(.aktif) {
  color: #52605a;
}

Kita menata pengecualiannya sekali, lalu melupakan urutan item di HTML.

Demo berikut memadukan dua pola di atas — pembatas dari li:not(:last-child) dan pengecualian a:not(.aktif):

Specificity Dihitung dari Argumennya #

Recap singkat dari section Cascade, Inheritance, dan Specificity: :not() sendiri tidak menambah bobot specificity; yang dihitung adalah selector di dalam argumennya. Bila argumennya berupa daftar, yang diambil adalah yang paling spesifik:

SelectorSpecificityPenjelasan
li:not(:last-child)(0, 1, 1)satu pseudo-class dari argumen + satu element
.menu-nav a:not(.aktif)(0, 2, 1)dua class + satu element
:not(#utama)(0, 1, 0)id di dalam argumen tetap dihitung penuh

Konsekuensi praktisnya: selector dengan :not() bisa lebih kuat dari yang terlihat. .tombol:not(.utama) membawa bobot dua class, sehingga aturan dasar .tombol saja tidak akan mampu menimpanya — perhitungan specificity harus selalu melibatkan isi kurung.

Kapan :not Membantu, Kapan Berlebihan #

:not() paling efektif ketika pengecualiannya jelas dan stabil: ujung daftar, state aktif, atau varian yang memang dikelola lewat class. Sebaliknya, rantai yang panjang dan bersarang cepat sulit diikuti:

css
/* Sah, tetapi sulit dibaca */
.kartu:not(:first-child):not(.unggulan) {
  margin-top: 12px;
}

Bila selector sudah butuh dua sampai tiga :not() untuk dijelaskan, pertimbangkan jalan sebaliknya — beri class positif seperti .kartu-berjarak — atau rapikan jaraknya lewat gap pada container. Keterbacaan stylesheet adalah bagian dari kualitas proyek, bukan pelengkap.

Saat menyusun selector dengan :not(), DevTools membantu memeriksa hasilnya tanpa menebak-nebak. Panel Styles di browser modern menyediakan tombol untuk memaksa state — :hover, :active, :focus — langsung dari halaman, sehingga aturan yang cocok dan yang kalah dapat dibaca dengan tenang. Kebiasaan ini mempercepat debugging selector, terutama ketika specificity dari argumen :not() terlibat; pemakaiannya sudah diperkenalkan pada chapter Debugging dengan Browser.

Satu batasan spesifikasi yang patut diingat: pseudo-element seperti ::before tidak boleh menjadi argumen :not(), karena negasi hanya bekerja pada selector yang memilih elemen.

Ringkasan #

:not() membalik pencocokan sehingga pengecualian bisa ditulis sekali saja: :not(:last-child) untuk ujung daftar, :not(.aktif) untuk item non-aktif, dan argumen daftar seperti :not(h1, h2) untuk banyak pengecualian sekaligus. Ingat dua konsekuensinya — specificity dihitung dari argumen, dan rantai :not() yang panjang menurunkan keterbacaan. Chapter berikutnya beralih dari pseudo-class ke pseudo-element pertama kita: ::before dan ::after, yang membuat kotak baru dari CSS semata.