The CSS Podcast - 003: Specificity
Supponiamo che tu stia lavorando con il seguente codice HTML e CSS:
<button class="branding">Hello, Specificity!</button>
.branding {
color: blue;
}
button {
color: red;
}
Esistono due regole che hanno come target lo stesso elemento. Ogni regola contiene una dichiarazione che vuole impostare il colore del pulsante: una tenta di colorarlo di rosso e l'altra di blu. Quale dichiarazione viene applicata all'elemento?
Comprendere l'algoritmo di specificità CSS è fondamentale per capire come il CSS decide tra le dichiarazioni in concorrenza.
La specificità è una delle fasi distinte della struttura a cascata, discussa nell'ultimo modulo sulla struttura a cascata.
Punteggio di specificità
A ogni regola del selettore all'interno di un'origine viene assegnato un punteggio. Puoi considerare la specificità come un punteggio totale e ogni tipo di selettore guadagna punti per quel punteggio. Vince la dichiarazione delle regole con la specificità più elevata.
Con la specificità di un progetto reale, il compito è assicurarsi che le regole CSS che prevedi di applicare si applichino, mantenendo generalmente bassi i punteggi per evitare complessità. La specificità deve essere solo il più elevata possibile, piuttosto che puntare alla specificità massima possibile. In futuro, potrebbe essere necessario applicare alcuni CSS effettivamente più importanti. Se scegli la specificità più elevata, complichi il compito.
La specificità non è un numero decimale, ma una triade composta da tre componenti: A
, B
e C
.
A
: specificità simile a IDB
: specificità simile a una classeC
: specificità simile a elemento
Spesso viene rappresentata utilizzando la notazione (A,B,C)
. Ad esempio: (1,0,2)
.
È comunemente utilizzata anche la notazione alternativa A-B-C
.
Confrontare le specificità
Le specificità vengono confrontate confrontando i tre componenti in ordine: la specificità con un valore A maggiore è più specifica; se i due valori A sono uguali, la specificità con un valore B maggiore è più specifica; se anche i due valori B sono uguali, la specificità con un valore C maggiore è più specifica; se tutti i valori sono uguali, le due specificità sono uguali.
Ad esempio, (1,0,0)
è considerata una specificità più elevata rispetto a (0,4,3)
perché il valore A
in (1,0,0)
(ovvero 1
)
è maggiore del valore A
di (0,4,3)
(ovvero 0
).
I selettori influiscono sulla specificità
Ogni parte della triade di specificità inizia con un valore 0
, quindi la specificità predefinita è (0,0,0)
.
Ogni parte di un selettore aumenta la specificità che, a seconda del tipo di selettore, incrementa il valore di A
, B
o C
.
Selettore universale
Un selettore universale (*
)
non aggiunge nessuna specificità, lasciando il valore nella specificità iniziale di (0,0,0)
.
* {
color: red;
}
Selettore elemento o pseudoelemento
Un selettore di elemento (tipo)
o di pseudo-elemento
aggiunge una specificità simile a quella degli elementi che incrementa il componente C
di 1
.
I seguenti esempi hanno una specificità complessiva di (0,0,1)
.
Selettore di tipo
div {
color: red;
}
Selettore di pseudo-elementi
::selection {
color: red;
}
Selettore di classe, pseudo-classe o attributo
Un selettore di classe,
pseudo-classe o
attributo aggiunge una specificità simile a quella della classe
che incrementa il componente B
di 1
.
I seguenti esempi hanno una specificità di (0,1,0)
.
Selettore di classe
.my-class {
color: red;
}
Selettore di pseudo-classi
:hover {
color: red;
}
Selettore di attributi
[href='#'] {
color: red;
}
Selettore ID
Un selettore ID aggiunge una specificità simile all'ID che incrementa il componente C
di 1,
a condizione che tu utilizzi un selettore ID (#myID
) e non un selettore di attributi ([id="myID"]
).
Nel seguente esempio, la specificità è (1,0,0)
#myID {
color: red;
}
Altri selettori
Il CSS ha molti selettori. Non tutti aggiungono specificità.
Ad esempio, la pseudoclasse :not()
non aggiunge nulla al calcolo della specificità.
Tuttavia, i selettori passati come argomenti vengono aggiunti al calcolo della specificità.
div:not(.my-class) {
color: red;
}
Questo campione ha una specificità di (0,1,1)
perché ha un selettore di tipo (div
) e una classe all'interno del :not()
.
Verificare di aver compreso
Verifica le tue conoscenze sul punteggio di specificità
Qual è la specificità di a[href="#"]
?
(0,0,1)
a
vale (0,0,1)
, ma [href="#"]
vale (0,1,0)
.(0,1,0)
a
vale (0,0,1)
, ma [href="#"]
vale (0,1,0)
.(0,1,1)
a
vale (0,0,1)
e [href="#"]
vale (0,1,1)
, per un'esattezza totale di (0,1,1)
.Fattori che non influiscono sulla specificità
Esistono alcuni fraintendimenti comuni in merito ai seguenti fattori che influiscono sulla specificità.
Attributi di stili in linea
Il CSS applicato direttamente all'attributo style
di un elemento
non influisce sulla specificità in quanto si tratta di un passaggio diverso nella cascata
che viene valutato prima della specificità.
<div style="color: red"></div>
Per eseguire l'override di questa dichiarazione all'interno di un foglio di stile, devi ricorrere a una dichiarazione vincente in un passaggio precedente della cascata.
Ad esempio, puoi aggiungere !important
,
in modo che diventi parte dell'origine !important
creata dall'autore.
!important
dichiarazioni
Un !important
alla fine di una dichiarazione CSS non influisce sulla specificità, ma inserisce la dichiarazione in un'origine diversa, ovvero Autore !important
.
Nell'esempio seguente, la specificità di .my-class
non è pertinente per la vittoria della dichiarazione !important
.
.my-class {
color: red !important;
color: white;
}
Quando due dichiarazioni sono !important
, la specificità entra di nuovo in gioco, poiché il passaggio di origine della serie non è stato ancora in grado di determinare il vincitore.
.branding {
color: blue !important;
}
button {
color: red !important;
}
Specificità nel contesto
Quando viene utilizzato un selettore complesso o composto, ogni parte del selettore contribuisce alla specificità. Considera questo esempio HTML:
<a class="my-class another-class" href="#">A link</a>
Questo link contiene due corsi.
La regola nel seguente CSS ha una specificità pari a (0,0,1)
:
a {
color: red;
}
Se fai riferimento a una delle classi nel selettore,
ora ha una specificità di (0,1,1)
:
a.my-class {
color: green;
}
Aggiungi l'altro gruppo al selettore,
ora ha una specificità di (0,2,1)
:
a.my-class.another-class {
color: rebeccapurple;
}
Aggiungi l'attributo href
al selettore,
ora ha una specificità di (0,3,1)
:
a.my-class.another-class[href] {
color: goldenrod;
}
Infine,aggiungi una pseudo-classe :hover
a tutto questo,
il selettore termina con una specificità di (0,4,1)
:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
Verificare di aver compreso
Verifica le tue conoscenze sul punteggio di specificità
Quale dei seguenti selettori ha una specificità di (0,2,1)
?
article > section
(0,0,2)
.article.card.dark
(0,2,1)
.article:hover a[href]
(0,0,1)
), un selettore attributo (del valore (0,0,1)
) e un selettore classe (del valore (0,0,1)
). Questo selettore ha quindi una specificità totale di (0,2,2)
.Aumentare pragmaticamente la specificità
Supponiamo che tu abbia del codice CSS simile al seguente:
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Con HTML simile al seguente:
<button class="my-button" onclick="alert('hello')">Click me</button>
Il pulsante ha uno sfondo grigio,
perché il secondo selettore ha una specificità di (0,1,1)
.
Questo perché ha un selettore di tipo (button
),
(0,0,1)
e un selettore di attributi ([onclick]
), (0,1,0)
.
La regola precedente (.my-button
) è uguale a (0,1,0)
perché ha un selettore di classe, che ha una specificità inferiore a (0,1,1)
.
Se vuoi migliorare questa regola, puoi ripetere il selettore di classe come segue:
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Ora il pulsante avrà uno sfondo blu, perché il nuovo selettore ha una specificità (0,2,0)
In caso di parità di specificità, viene applicato il passaggio successivo della struttura a cascata
Per il momento, rimaniamo con l'esempio del pulsante e cambiamo il CSS in questo modo:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
Il pulsante ha uno sfondo grigio,
perché entrambi i selettori hanno una specificità identica di (0,1,0)
.
Se cambi l'ordine delle regole nell'origine, il pulsante diventerà blu.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
Questo perché entrambi i selettori hanno la stessa specificità. In questo caso, la struttura a cascata torna al passaggio relativo all'ordine di visualizzazione.