Specificità

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 ID
  • B: specificità simile a una classe
  • C: 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.

Un diagramma che mostra i tre componenti della specificità (A,B,C). Per ogni componente, il diagramma mostra cosa rappresenta e alcuni esempi di selettori che lo interessano.
Un diagramma che mostra il componente di specificità influenzato dai vari selettori.

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)
Riprova. 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
Gli elementi aggiungono una specificità simile agli elementi (componente "C"). Il selettore contiene due elementi, pertanto ha una specificità pari a (0,0,2).
article.card.dark
Gli elementi aggiungono una specificità simile agli elementi (componente "C") e le classi aggiungono una specificità simile alle classi (componente "B"). Con due classi e un elemento, questo selettore ha una specificità di (0,2,1).
article:hover a[href]
Gli elementi aggiungono una specificità simile agli elementi (componente "C"), mentre le pseudoclassi e gli attributi aggiungono una specificità simile alle classi (componente "B"). Sono presenti due selettori elementi (2 × (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.

Risorse