Kekhususan

The CSS Podcast - 003: Spesifisitas

Misalkan Anda bekerja dengan HTML dan CSS berikut:

<button class="branding">Hello, Specificity!</button>
.branding {
  color: blue;
}

button {
  color: red;
}

Ada dua aturan yang menargetkan elemen yang sama di sini. Setiap aturan berisi deklarasi yang ingin menetapkan warna tombol: satu mencoba mewarnai tombol merah dan yang lain mencoba mewarnai tombol biru. Deklarasi mana yang diterapkan ke elemen?

Memahami algoritma spesifisitas CSS adalah kunci untuk memahami cara CSS memutuskan antara deklarasi yang bersaing.

Spesifisitas adalah salah satu tahap berbeda dari susunan, yang dibahas dalam modul terakhir, tentang susunan.

Penskoran spesifisitas

Setiap aturan pemilih dalam asal mendapatkan skor. Anda dapat menganggap spesifisitas sebagai skor total dan setiap jenis pemilih memperoleh poin untuk skor tersebut. Deklarasi dari aturan dengan spesifisitas tertinggi akan menang.

Dengan spesifisitas dalam project nyata, tindakan penyeimbangan adalah memastikan aturan CSS yang Anda harapkan diterapkan, benar-benar diterapkan, sekaligus menjaga skor tetap rendah untuk mencegah kompleksitas. Spesifisitas hanya boleh setinggi yang kita butuhkan, daripada berupaya mendapatkan spesifisitas setinggi mungkin. Di masa mendatang, beberapa CSS yang benar-benar lebih penting mungkin perlu diterapkan. Jika Anda memilih spesifisitas tertinggi, pekerjaan tersebut akan sulit.

Kekhususan bukan berupa angka desimal, tetapi triad yang terdiri dari tiga komponen: A, B, dan C.

  • A: spesifisitas seperti ID
  • B: spesifisitas seperti class
  • C: spesifisitas seperti elemen

Hal ini sering kali direpresentasikan menggunakan notasi (A,B,C). Contoh: (1,0,2). Notasi alternatif A-B-C juga umum digunakan.

Diagram yang menunjukkan tiga komponen spesifisitas (A,B,C). Untuk setiap komponen, diagram menunjukkan apa yang diwakilinya dan beberapa contoh pemilih yang memengaruhinya.
Diagram yang menunjukkan komponen spesifisitas yang dipengaruhi oleh berbagai pemilih.

Cara membandingkan spesifisitas

Spesifisitas dibandingkan dengan membandingkan ketiga komponen secara berurutan: spesifisitas dengan nilai A yang lebih besar lebih spesifik; jika kedua nilai A sama, maka spesifisitas dengan nilai B yang lebih besar lebih spesifik; jika kedua nilai B juga sama, maka spesifisitas dengan nilai C yang lebih besar lebih spesifik; jika semua nilai sama, kedua spesifisitas sama.

Misalnya, (1,0,0) dianggap memiliki spesifisitas yang lebih tinggi daripada (0,4,3) karena nilai A dalam (1,0,0) (yaitu 1) lebih besar daripada nilai A dari (0,4,3) (yaitu 0).

Pemilih memengaruhi spesifisitas

Setiap bagian dalam triad spesifisitas dimulai dengan nilai 0, sehingga spesifisitas default adalah (0,0,0). Setiap bagian pemilih meningkatkan spesifisitas yang, bergantung pada jenis pemilih, meningkatkan nilai A, B, atau C.

Pemilih universal

Selektor universal (*) tidak menambahkan spesifisitas, sehingga nilainya tetap pada spesifisitas awal (0,0,0).

* {
  color: red;
}

Pemilih elemen atau pseudo-elemen

Selektor elemen (jenis) atau pseudo-elemen menambahkan spesifisitas seperti elemen yang meningkatkan komponen C sebesar 1.

Contoh berikut memiliki spesifisitas keseluruhan (0,0,1).

Pemilih jenis

div {
  color: red;
}

Pemilih elemen semu

::selection {
  color: red;
}

Pemilih class, pseudo-class, atau atribut

Pemilih class, pseudo-class, atau atribut menambahkan spesifisitas seperti class yang meningkatkan komponen B sebesar 1.

Contoh berikut memiliki spesifisitas (0,1,0).

Pemilih class

.my-class {
  color: red;
}

Pemilih pseudo-class

:hover {
  color: red;
}

Pemilih atribut

[href='#'] {
  color: red;
}

Pemilih ID

Selektor ID menambahkan spesifisitas seperti ID yang meningkatkan komponen A sebesar 1, selama Anda menggunakan selektor ID (#myID) dan bukan selektor atribut ([id="myID"]).

Dalam contoh berikut, spesifisitasnya adalah (1,0,0)

#myID {
  color: red;
}

Pemilih lainnya

CSS memiliki banyak pemilih. Tidak semuanya menambahkan kekhususan. Misalnya, class semu :not() itu sendiri tidak menambahkan apa pun ke penghitungan spesifisitas.

Spesifisitas class semu :not() digantikan oleh spesifisitas pemilih yang paling spesifik dalam argumen pemilih yang dipisahkan koma; memberikan spesifisitas yang sama seolah-olah ditulis :not(:is(argument)).

div:not(.my-class) {
  color: red;
}

Pseudo-class :is() juga tidak menambah perhitungan spesifisitas. Seperti :not(), fungsi ini mengambil spesifisitas argumennya yang paling spesifik.

:is(h1, h2, h3) {
  color: blue;
}

Contoh ini memiliki spesifisitas (0,0,1) karena hanya memiliki satu jenis pemilih (type).

Dengan penambahan id, spesifisitas meningkat menjadi (1,0,0).

:is(h1, h2, h3, #my-heading) {
  color: blue;
}

Pseudokelas :where() berbeda. Terlepas dari kekhususan argumennya, selalu memiliki kekhususan (0,0,0).

:where(h1, h2, h3, #my-heading) {
  color: blue;
}

Gaya spesifisitas rendah yang diterapkan menggunakan :where() memungkinkan Anda mengganti gaya ini dengan pemilih dasar di lembar gaya Anda nanti:

:where(#my-content) {
   color: red;
}

p {
   color: blue;
}

Meskipun :where() memiliki id dalam daftar argumennya, spesifisitasnya tetap hanya (0, 0, 0), sehingga pemilih p dasar akan menggantikannya dan teks akan menjadi blue.

Uji pemahaman Anda

Uji pengetahuan Anda tentang pemberian skor spesifisitas

Apa spesifisitas a[href="#"]?

(0,0,1)
a bernilai (0,0,1), tetapi [href="#"] bernilai (0,1,0).
(0,1,0)
Coba lagi. a bernilai (0,0,1), tetapi [href="#"] bernilai (0,1,0).
(0,1,1)
a bernilai (0,0,1) dan [href="#"] bernilai (0,1,0), sehingga total spesifisitasnya adalah (0,1,1).

Faktor yang tidak memengaruhi spesifisitas

Ada beberapa kesalahpahaman umum tentang faktor-faktor berikut yang memengaruhi spesifisitas.

Atribut gaya sebaris

CSS yang diterapkan langsung ke atribut style elemen, tidak memengaruhi spesifisitas karena merupakan langkah berbeda dalam kaskade yang dievaluasi sebelum spesifisitas.

<div style="color: red"></div>

Untuk mengganti deklarasi ini dari dalam lembar gaya, Anda harus menggunakan deklarasi yang menang pada langkah sebelumnya dalam kaskade.

Misalnya, Anda dapat menambahkan !important ke dalamnya, sehingga menjadi bagian dari origin !important yang Ditulis.

!important pernyataan

!important di akhir deklarasi CSS tidak memengaruhi spesifisitas tetapi menempatkan deklarasi di origin yang berbeda, yaitu Authored !important.

Dalam contoh berikut, spesifisitas .my-class tidak relevan agar deklarasi !important menang.

.my-class {
  color: red !important;
  color: white;
}

Jika dua deklarasi adalah !important, maka spesifisitas akan berperan lagi, karena langkah asal dari susunan bertingkat belum dapat menentukan pemenang.

.branding {
  color: blue !important;
}

button {
  color: red !important;
}

Kekhususan dalam konteks

Saat pemilih kompleks atau gabungan digunakan, setiap bagian pemilih tersebut akan menambah spesifisitas. Perhatikan contoh HTML ini:

<a class="my-class another-class" href="#">A link</a>

Link ini memiliki dua kelas. Aturan dalam CSS berikut memiliki spesifisitas (0,0,1):

a {
  color: red;
}

Jika Anda mereferensikan salah satu class dalam pemilih, class tersebut kini memiliki spesifisitas (0,1,1):

a.my-class {
  color: green;
}

Tambahkan class lain ke pemilih, sekarang memiliki spesifisitas (0,2,1):

a.my-class.another-class {
  color: rebeccapurple;
}

Tambahkan atribut href ke pemilih, sekarang memiliki spesifisitas (0,3,1):

a.my-class.another-class[href] {
  color: goldenrod;
}

Terakhir,tambahkan class semu :hover ke semua itu, pemilih akan berakhir dengan spesifisitas (0,4,1):

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Uji pemahaman Anda

Uji pengetahuan Anda tentang pemberian skor spesifisitas

Manakah dari pemilih berikut yang memiliki spesifisitas (0,2,1)?

article > section
Elemen menambahkan spesifisitas seperti elemen (`C` komponen). Ada 2 elemen dalam pemilih, sehingga memiliki spesifisitas (0,0,2).
article.card.dark
Elemen menambahkan spesifisitas seperti elemen (komponen `C`) dan class menambahkan spesifisitas seperti class (komponen `B`). Dengan 2 class dan 1 elemen, pemilih ini memiliki kekhususan (0,2,1).
article:hover a[href]
Elemen menambahkan spesifisitas seperti elemen (komponen `C`), pseudo-class dan atribut menambahkan spesifisitas seperti class (komponen `B`). Ada 2 pemilih elemen (2 × (0,0,1)), pemilih atribut (bernilai (0,1,0)), dan pemilih class (bernilai (0,1,0)). Hal ini membuat pemilih ini memiliki spesifisitas total (0,2,2).

Meningkatkan spesifisitas secara pragmatis

Misalnya, Anda memiliki beberapa CSS yang terlihat seperti ini:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Dengan HTML yang terlihat seperti ini:

<button class="my-button" onclick="alert('hello')">Click me</button>

Tombol memiliki latar belakang abu-abu, karena pemilih kedua memiliki spesifisitas (0,1,1). Hal ini karena memiliki satu pemilih jenis (button), yaitu (0,0,1) dan pemilih atribut ([onclick]), yaitu (0,1,0).

Aturan sebelumnya—.my-button—sama dengan (0,1,0) karena memiliki satu pemilih class, yang memiliki spesifisitas lebih rendah daripada (0,1,1).

Jika Anda ingin meningkatkan kualitas aturan ini, Anda dapat mengulangi pemilih class seperti ini:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Sekarang, tombol akan memiliki latar belakang biru, karena pemilih baru mendapatkan spesifisitas (0,2,0)

Jika spesifisitas sama, maka akan beralih ke langkah berikutnya dalam susunan bertingkat

Melanjutkan contoh tombol untuk saat ini, ubah CSS menjadi seperti ini:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

Tombol memiliki latar belakang abu-abu, karena kedua pemilih memiliki kekhususan yang identik, yaitu (0,1,0).

Jika Anda menukar aturan dalam urutan sumber, tombol akan berwarna biru.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

Hal ini karena kedua pemilih memiliki kekhususan yang sama. Dalam hal ini, susunan akan kembali ke langkah urutan tampilan.

Resource