La cascade CSS: come il browser sceglie chi vince
Origine, specificità e ordine, !important e i cascade layers
La C di CSS sta per Cascading, cioè «a cascata». È la parola più importante del nome. Prima o poi ti capiterà: due regole diverse vogliono dare un colore diverso allo stesso testo. Chi vince? Il browser non tira a caso: segue una procedura precisa, sempre la stessa.
Davanti a due regole in conflitto, il browser si fa tre domande, in quest'ordine preciso, e passa alla successiva solo in caso di pareggio:
- Da dove arriva la regola? (origine e importanza)
- Quanto è mirato il selettore? (specificità)
- Quale è scritta per ultima? (ordine di apparizione)
1. L'origine: chi ha scritto la regola?
Gli stili possono arrivare da tre fonti diverse: il browser (gli stili di default), l'utente (le preferenze di chi visita il sito) e l'autore, cioè tu che sviluppi. In condizioni normali l'ordine di forza è: browser < utente < autore. Tradotto: i tuoi stili battono quasi sempre quelli predefiniti del browser.
Quegli stili predefiniti hanno un nome: user agent stylesheet. Sono le regole di base che ogni browser applica da solo: è per questo che un <h1> appare grande e in grassetto, e i link blu e sottolineati, anche senza una riga di CSS scritta da te.
Fonte: MDN Web Docs: «Introduction to the CSS cascade» (origin types).
2. La specificità: quanto è mirato il selettore?
Quando le regole in conflitto arrivano dalla stessa origine, il browser conta quanto è preciso ciascun selettore. Il punteggio si scrive su tre colonne, ID - CLASSE - TIPO:
- #logo un ID vale 1-0-0
- .titolo una classe (o attributo, o pseudo-classe come :hover) vale 0-1-0
- h1 un elemento (o pseudo-elemento) vale 0-0-1
Si confrontano le colonne da sinistra: un solo ID batte qualsiasi numero di classi. Gli stili inline (scritti nell'attributo style="…") vincono su tutti i selettori.
Esempio: le tre regole competono sullo stesso titolo. Vince l'ID.
<style>
#titolo { color: blue; } /* 1-0-0 <- vince */
.evidenza { color: green; } /* 0-1-0 */
h1 { color: red; } /* 0-0-1 */
</style>
<h1 id="titolo" class="evidenza">Ciao</h1>
La specificità è come l'indirizzo su una lettera. «A chi abita in Italia» (elemento) è vago; «Alla famiglia Rossi, Via Roma 10» (ID) è preciso. Il postino consegna all'indirizzo più mirato, e così fa il browser con lo stile.
Per non impazzire con i conteggi esiste lo specificity calculator (MDN ne segnala uno): incolli il selettore e ti dice il punteggio. Utile anche sapere che :where() e l'universale * valgono 0-0-0: comodi per tenere la specificità bassa.
Fonte: MDN Web Docs: «Specificity» (guida al calcolo ID-CLASSE-TIPO).
3. L'ordine: a parità di tutto, vince l'ultima
Se due regole hanno la stessa origine e la stessa specificità, allora, e solo allora, vince quella scritta più in basso nel foglio di stile. L'ultima parola conta.
!important: la carta jolly (da usare con parsimonia)
Aggiungendo !important dopo un valore, quella dichiarazione batte tutte le regole normali, ignorando la specificità e ribaltando persino l'ordine delle origini. Sembra comodo, ma è una trappola.
p { color: red !important; } /* vince, a prescindere */
La raccomandazione ufficiale è chiara: usalo con parsimonia, e quando puoi risolvi il conflitto con la specificità o con i cascade layers.
Fonte: MDN Web Docs: «!important» (keyword) e «Specificity» (best practice).
I cascade layers (@layer): l'alternativa moderna
La regola @layer ti permette di definire gruppi di stili con priorità esplicita, decidi tu chi vince senza trucchi di specificità né !important. La regola: il layer dichiarato prima ha priorità più bassa, quello dichiarato dopo più alta; e gli stili fuori da ogni layer battono quelli dentro i layer.
@layer bootstrap, mio-tema; /* mio-tema vince su bootstrap */
@layer bootstrap {
.btn {
background: gray;
}
}
@layer mio-tema {
.btn {
background: purple;
} /* <- si applica questo */
}
Possiamo immaginare dei fogli trasparenti impilati su una lavagna luminosa: il foglio in cima copre quelli sotto. Decidi tu l'ordine della pila, in modo chiaro e prevedibile.
Sono perfetti quando mescoli il tuo CSS con quello di terze parti (per esempio Bootstrap): metti il framework in un layer e i tuoi stili lo sovrascrivono con ordine, senza guerre di !important.
Fonte: MDN Web Docs: «@layer» (at-rule) e «Cascade layers».
In sintesi
| # | Il browser controlla… | Cioè | Esempio |
|---|---|---|---|
| 1 | Origine e importanza | Chi ha scritto la regola, più !important e @layer | I tuoi stili battono quelli del browser |
| 2 | Specificità | Quanto è mirato il selettore: ID > classe > elemento | #logo batte .titolo batte h1 |
| 3 | Ordine | A parità di tutto, vince l'ultima scritta | L'ultima regola identica vince |
La cascade non è magia né casualità: è un arbitro con un regolamento preciso. Compreso l'ordine delle domande, saprai sempre spiegare perché uno stile si applica e perché un altro no.
Commenti (0)
Registrati per commentare, fare domande e proporre l'argomento della prossima pillola (oppure accedi se hai già un account).
Nessun commento. Sii il primo a scrivere qualcosa.