CSS
Cascading e Specificità
Ricerca…
Osservazioni
La specificità dei CSS intende promuovere la concisione del codice consentendo all'autore di definire alcune regole generali di formattazione per un ampio insieme di elementi e quindi di sovrascriverli per un determinato sottoinsieme.
Cascading
Cascading e specificità sono usati insieme per determinare il valore finale di una proprietà di stile CSS. Definiscono inoltre i meccanismi per risolvere i conflitti nelle serie di regole CSS.
Ordine di caricamento CSS
Gli stili sono letti dalle seguenti fonti, in questo ordine:
- Foglio di stile User Agent (gli stili forniti dal fornitore del browser)
- Foglio di stile dell'utente (Lo stile aggiuntivo che un utente ha impostato sul suo browser)
- Stili di autore (qui autore indica il creatore della pagina web / sito Web)
- Forse uno o più file
.css
- Nell'elemento
<style>
del documento HTML
- Forse uno o più file
- Stili in linea (nell'attributo
style
su un elemento HTML)
Il browser cercherà gli stili corrispondenti durante il rendering di un elemento.
Come vengono risolti i conflitti?
Quando solo una serie di regole CSS sta tentando di impostare uno stile per un elemento, non vi è alcun conflitto e tale serie di regole viene utilizzata.
Quando vengono trovati più set di regole con impostazioni in conflitto, prima le regole di specificità e quindi le regole a cascata vengono utilizzate per determinare quale stile utilizzare.
Esempio 1 - Regole di specificità
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
Di che colore sarà il testo? (passa il mouse per vedere la risposta)
blu
Prima vengono applicate le regole di specificità e quella con la specificità più alta "vince".
Esempio 2 - Regole in cascata con selettori identici
File css esterno
.class {
background: #FFF;
}
Css interno (nel file HTML)
<style>
.class {
background: #000;
}
<style>
In questo caso, in cui si hanno selettori identici, la cascata si attiva e determina che l'ultimo caricato "vince".
Esempio 3: regole a cascata dopo le regole di specificità
body > .mystyle { background-color: blue; } /* specificity: 0, 0, 1, 1 */
.otherstyle > div { background-color: red; } /* specificity: 0, 0, 1, 1 */
<body class="otherstyle">
<div class="mystyle">Hello World</div>
</body>
Di che colore sarà lo sfondo?
rosso
Dopo aver applicato le regole di specificità, c'è ancora un conflitto tra blu e rosso, quindi le regole a cascata vengono applicate in aggiunta alle regole di specificità. Il collegamento in cascata esamina l'ordine di caricamento delle regole, sia all'interno dello stesso file .css
che nella raccolta di fonti di stile. L'ultimo caricato sovrascrive quelli precedenti. In questo caso, la regola del " .otherstyle > div
" vince ".
Un'ultima nota
- La specificità del selettore ha sempre la precedenza.
- Legami di rottura dell'ordine di fogli di stile.
- Gli stili in linea vincono tutto.
La! Dichiarazione importante
La dichiarazione !important
viene utilizzata per ignorare la solita specificità in un foglio di stile dando una priorità più alta a una regola. Il suo utilizzo è: property : value !important;
#mydiv {
font-weight: bold !important; /* This property won't be overridden
by the rule below */
}
#outerdiv #mydiv {
font-weight: normal; /* #mydiv font-weight won't be set to normal
even if it has a higher specificity because
of the !important declaration above */
}
Evitare l'uso di !important
è fortemente raccomandato (a meno che non sia assolutamente necessario), perché disturberà il flusso naturale delle regole CSS che può portare incertezza nel tuo foglio di stile. Inoltre è importante notare che quando più dichiarazioni !important
sono applicate alla stessa regola su un determinato elemento, quella con la specificità più alta sarà l'ona applicata.
Ecco alcuni esempi in cui l'uso di una dichiarazione !important
può essere giustificato:
- Se le tue regole non devono essere sovrascritte da alcuno stile in linea dell'elemento che è scritto all'interno dell'attributo
style
dell'elemento html. - Per dare all'utente un maggiore controllo sull'accessibilità del web, come aumentare o diminuire la dimensione della dimensione del font, ignorando lo stile dell'autore usando
!important
. - Per testare e fare il debug usando l'elemento inspect.
Guarda anche:
Calcolo della specificità del selettore
Ogni singolo selettore CSS ha il proprio valore di specificità. Ogni selettore in una sequenza aumenta la specificità complessiva della sequenza. I selettori rientrano in uno dei tre diversi gruppi di specificità: A , B e c . Quando più sequenze di selettori selezionano un determinato elemento, il browser utilizza gli stili applicati dalla sequenza con la massima specificità complessiva.
Gruppo | Composto da | Esempi |
---|---|---|
UN | selettori di identificazione | #foo |
B | selettori di classe selettori di attributi pseudo-classi | .bar [title] , [colspan="2"] :hover :nth-child(2) |
c | selezionare i selettori pseudo-elementi | div , li ::before , ::first-letter |
Il gruppo A è il più specifico, seguito dal gruppo B , infine il gruppo c .
Il selettore universale ( *
) e i combinatori (come >
e ~
) non hanno specificità.
Esempio 1: specificità delle varie sequenze di selettori
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
Esempio 2: come viene utilizzata la specificità dal browser
Immagina la seguente implementazione CSS:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Qui abbiamo un selettore ID che dichiara il color
come blu e un selettore di classe che dichiara il color
come rosso e lo background
come nero .
Un elemento con un ID di #foo
e una classe di .bar
saranno selezionati da entrambe le dichiarazioni. I selettori ID hanno una specificità di Gruppo A e i selettori di classe hanno una specificità di Gruppo B. Un selettore ID supera ogni numero di selettori di classe. Per questo color:blue;
, color:blue;
dal selettore #foo
e dallo background:black;
dal selettore .bar
verrà applicato all'elemento. La maggiore specificità del selettore ID farà sì che il browser ignori la .bar
di color
del selettore .bar
.
Ora immagina una diversa implementazione CSS:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Qui abbiamo due selettori di classe; uno dei quali dichiara il color
come rosso e lo background
come nero e l'altro dichiara lo background
come bianco .
Un elemento con entrambe le classi .bar
e .baz
sarà influenzato da entrambe queste dichiarazioni, tuttavia il problema che abbiamo ora è che sia .bar
che .baz
hanno una specificità identica di Gruppo B. La natura a cascata di CSS risolve questo per noi: come .baz
è definito dopo .bar
, il nostro elemento finisce con il color
rosso da .bar
ma lo background
bianco da .baz
.
Esempio 3: come manipolare la specificità
L'ultimo frammento dell'esempio 2 può essere manipolato per garantire che la nostra .bar
di color
del selettore di classe .bar
venga utilizzata al posto di quella del selettore di classe .baz
.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
Il modo più comune per ottenere questo risultato è scoprire quali altri selettori possono essere applicati alla sequenza del selettore .bar
. Ad esempio, se la .bar
classe è stata sempre e solo applicato a span
elementi, potremmo modificare il .bar
selettore span.bar
. Ciò gli darebbe una nuova specificità di Gruppo C , che .baz
la mancanza del selettore .baz
:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
Tuttavia, potrebbe non essere sempre possibile trovare un altro selettore comune condiviso tra qualsiasi elemento che utilizza la classe .bar
. Per questo motivo, il CSS ci consente di duplicare i selettori per aumentare la specificità. Invece di solo .bar
, possiamo usare invece .bar.bar
(vedi La grammatica dei selettori, Raccomandazione W3C ). Questo seleziona ancora qualsiasi elemento con una classe di .bar
, ma ora ha il doppio della specificità di Gruppo B :
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
Dichiarazioni di stile !important
e in linea
Il flag !important
su una dichiarazione di stile e gli stili dichiarati dall'attributo di style
HTML sono considerati con una maggiore specificità rispetto a qualsiasi selettore. Se questi esistono, la dichiarazione di stile che hanno influenza annullerà altre dichiarazioni indipendentemente dalla loro specificità. Cioè, a meno che tu non abbia più di una dichiarazione che contiene un flag !important
per la stessa proprietà che si applica allo stesso elemento. Quindi, le normali regole di specificità si applicano a quelle proprietà in riferimento l'una all'altra.
Dal momento che superano completamente la specificità, l'uso di !important
è disapprovato nella maggior parte dei casi d'uso. Uno dovrebbe usarlo il meno possibile. Per mantenere il codice CSS efficiente e mantenibile a lungo termine, è quasi sempre preferibile aumentare la specificità del selettore circostante che usare !important
.
Una di quelle rare eccezioni in cui !important
non è disapprovato, è quando si implementano classi helper generiche come una classe .hidden
o .background-yellow
che devono sempre sovrascrivere una o più proprietà ovunque si trovino. E anche allora, devi sapere cosa stai facendo. L'ultima cosa che vuoi, quando scrivi CSS gestibile, è avere !important
flag in tutto il tuo CSS.
Un'ultima nota
Un malinteso comune sulla specificità dei CSS è che i valori dei gruppi A , B e c dovrebbero essere combinati tra loro ( a=1, b=5, c=1
=> 151). Questo non è il caso. In tal caso, disporre di 20 di un selettore di gruppo B o c sarebbe sufficiente per ignorare rispettivamente un singolo selettore di gruppo A o B. I tre gruppi dovrebbero essere considerati come livelli individuali di specificità. La specificità non può essere rappresentata da un singolo valore.
Quando crei il tuo foglio di stile CSS, dovresti mantenere la specificità più bassa possibile. Se è necessario aumentare leggermente la specificità per sovrascrivere un altro metodo, renderlo più alto ma più basso possibile per renderlo più alto. Non dovresti avere bisogno di un selettore come questo:
body.page header.container nav div#main-nav li a {}
Questo rende le modifiche future più difficili e inquina quella pagina css.
Puoi calcolare la specificità del tuo selettore qui
Esempio di specificità più complesso
div {
font-size: 7px;
border: 3px dotted pink;
background-color: yellow;
color: purple;
}
body.mystyle > div.myotherstyle {
font-size: 11px;
background-color: green;
}
#elmnt1 {
font-size: 24px;
border-color: red;
}
.mystyle .myotherstyle {
font-size: 16px;
background-color: black;
color: red;
}
<body class="mystyle">
<div id="elmnt1" class="myotherstyle">
Hello, world!
</div>
</body>
Quali sono i bordi, i colori e le dimensioni dei caratteri del testo?
dimensione del font:
font-size: 24;
, poiché la#elmnt1
regole#elmnt1
ha la specificità più alta per il<div>
in questione, ogni proprietà qui è impostata.
confine:
border: 3px dotted red;
. Il colore del bordored
è preso dal set di regole#elmnt1
, poiché ha la massima specificità. Le altre proprietà del bordo, dello spessore del bordo e dello stile del bordo provengono dalla serie di regolediv
.
colore di sfondo:
background-color: green;
. Ilbackground-color
è impostato nelle serie dibody.mystyle > div.myotherstyle
div
,body.mystyle > div.myotherstyle
e.mystyle .myotherstyle
. Le specificità sono (0, 0, 1) contro (0, 2, 2) vs. (0, 2, 0), quindi il medio "vince".
colore:
color: red;
. Il colore è impostato in entrambi i.mystyle .myotherstyle
regolediv
e.mystyle .myotherstyle
. Quest'ultimo ha la specificità più alta di (0, 2, 0) e "vince".