-
raxell.
User deleted
CSS - Specificità dei selettori Cos'è
Le regole di specificità dei selettori vengono usate dal browser per determinare quali proprietà devono essere applicate ai vari elementi della pagina.
Se vi è mai capitato di non veder applicate alcune regole CSS e non ve ne spiegate il motivo, probabilmente è perchè nella pagina erano presenti selettori con specificità maggiore che sovrascrivevano suddette regole.
La regola di base nei CSS è che, su uno stesso elemento e a parità di specificità, vengono applicati gli stili dichiarati per ultimi. Ad esempio le seguenti regole:CODICEp {color: blue}
p {color: red}
applicano due proprietà identiche a uno stesso elemento, ma a prevalere è l'ultima ad essere stata dichiarata (i paragrafi avranno quindi testo rosso).
Cosa succede però con un qualcosa di questo tipo?CODICE<div id="text">
<p class="ptext">paragraph</p>
</div>CODICE#text p {color: red}
p.ptext {color: green}
p {color: blue}
Tutti i selettori si riferiscono allo stesso elemento, ma quali stili saranno applicati? A rigor di logica dovrebbe prevalere il selettore con specificità (o peso) maggiore, ma qual'è? Per capirlo occorre aver chiare le seguenti regole:- gli stili inline (es.
style="color: black"
) hanno specificità massima e sovrascivono qualsiasi stile - i selettori ID (es.
#text
) hanno specificità maggiore di ogni altro selettore - i selettori classe (es.
.ptext
), pseudo-classe (es.:hover
) e attributo (es.[type="submit"]
) hanno specificità maggiore dei selettori HTML (es.p
) - i selettori universali (
*
), combinatori (+
,>
,~
) e di negazione (:not()
) non hanno effetto sulla specificità
La specificità può essere vista come un peso attribuito ai selettori. Se due selettori che si riferiscono a uno stesso elemento hanno definite delle stesse proprietà, saranno applicate quelle del selettore con peso maggiore.
E' importante notare che la specificità si applica solo in caso di conflitto tra le proprietà dei selettori, ogni stile non in conflitto viene applicato regolarmente. In questo esempioCODICE<div id="text">
<p class="ptext">paragraph</p>
</div>CODICE#text p {color: red}
p.ptext {color: blue; text-decoration: underline}
p {font-weight: bold}
l'unica proprietà in conflitto ècolor
, tutte le altre vengono applicate in modo trasparente.Come calcolarla
A meno di aver a che fare con selettori particolarmente lunghi, dopo un po' si riconosce a colpo d'occhio quale selettore prevale sugli altri.
E' comunque sempre utile sapere come calcolarla, e il modo più semplice è, partendo da 0 sommare:- 100 per ogni ID del selettore
- 10 per ogni classe, pseudo-classe, attributo
- 1 per ogni elemento HTML o pseudo-elemento
Nell'esempio precedente:CODICE<div id="text">
<p class="ptext">paragraph</p>
</div>CODICE#text p {color: red}
p.ptext {color: green}
p {color: blue}#text p
avrà un peso di 101 (100 per#text
+ 1 perp
),p.ptext
un peso di 11 (10 per.ptext
+ 1 perp
) ep
un peso di 1. Di conseguenza prevarrà il selettore più specifico#text p
e il paragrafo avrà quindi testo rosso.
NB: I selettori ID sono solo quelli preceduti dal cancelletto (es:#text
), selettori del tipo[id="text"]
sono da considerarsi come selettori di attributo. Discorso analogo vale per le classi.Sull'uso di !important
La regola!important
ha come effetto quello di sovrascrivere qualsiasi altra proprietà dichiarata. Per questo motivo è in genere considerata una cattiva abitudine in quanto rende il debugging impossibile: una regola dichiarata con!important
può essere sovrascritta solo da un altro!important
, che può essere sovrascritto solo da un altro!important
e così via. Diventa impossibile comprendere una catena di sovrascritture di questo tipo.
In generale l'uso di!important
andrebbe sempre evitato. Ha senso usarlo solo se si ha la necessità di sovrascrivere degli stili inline (es.style="color: black"
) che non sono direttamente sotto il nostro controllo. Se gli stili inline contengono a loro volta degli!important
non c'è modo di sovrascriverli.
Quando non si ha idea del perchè alcuni stili non vengono applicati, piuttosto che mettere una pezza con!important
, è più utile capire quale altro selettore più specifico sta sovrascrivendo la nostra dichiarazione.
Quindi, per definire i selettori è bene considerare queste due regole:- rendere i selettori più corti possibili: sovraspecificare un selettore, oltre ad essere meno performante, rende eventuali sovrascritture di stili più difficili.
Preferire.ptext
al posto didiv p.ptext
Anche anteporre qualsiasi selettore a un ID è assolutamente inutile, un ID è per definizione univoco e aumentarne la specificità è una cosa insensata. - rendere il selettore più specifico invece di usare !important: quando si vuole sovrascrivere degli stili considerare l'aggiunta di una classe o un id invece di appenderci un
!important
.
Esempi
Selettore Specificità .menuwrap 10 p 1 #board 100 body > div:first-of-type 12 * 0 div:first-child > * 11 .stats .bottom .zz > div:first-child > * > * 41 .left .menu:first-child > ul 31 .profile dt[class] 21 #forum .left > .menu:last-child > ul 131 .forminput[type="submit"] 20 *:before 1 .left > li:not([class]):nth-of-type(2) > span 32 .menuwrap .search > input:last-child:focus 41 #topic .post > p:first-letter 112 . - gli stili inline (es.
-
.
Bella guida .