Dopo aver imparato come si dichiarano a livello sintattico i costrutti base di un CSS e conosciuto i selettori, dobbiamo capire anche in che modo regole e proprietà interagiscono tra di loro nel contesto di un foglio di stile. Sono concetti teorici di importanza cruciale e propedeutici rispetto alle lezioni che seguono.
Ereditarietà
Il primo concetto è quello di ereditarietà. Secondo questo meccanismo le impostazioni di stile applicate ad un elemento
vengono ereditate anche dai suoi discendenti. Almeno fino a quando, per un elemento discendente, non si imposti esplicitamente un valore diverso per quella proprietà.
Vediamo di chiarire con un esempio. Impostiamo il colore grigio scuro per il testo a livello dell'elemento body
:
body {color: #222;}
Tutti gli elementi discendenti di body
, erediteranno questa impostazione. Ma se ad un certo punto definiamo nel codice del CSS un selettore con la proprietà color: white;
l'ereditarietà viene spezzata:
body {color: #222;}
li {color: white;}
Gli elementi li
avranno perciò il testo bianco.
Non tutte le proprietà sono ereditate e lo renderemo esplicito nell'analisi di ciascuna di esse. In genere le proprietà non ereditate sono quelle attinenti la formattazione del box model: margini, bordi, padding, background le più importanti. Il motivo è semplice. Ereditare un bordo è semplicemente senza senso. Se ne imposto uno, diciamo, per un paragrafo sarebbe assurdo che un elemento a
o un testo in grassetto vengano circondati dallo stesso bordo!
Fin qui tutto semplice. Ora scendiamo nei dettagli. L'ereditarietà non basta a spiegare le molteplici possibilità di relazione tra le regole di un CSS.
Peso e origine
Da qui in avanti affronteremo un'altra serie di concetti fondamentali tutti riconducibili comunque ad uno stesso ambito: i conflitti possibili tra gli stili e le regole. Tenteremo in pratica di rispondere a quesiti come questo: se definisco queste regole in un CSS
p {color: black;}
.testo {color: white;}
e in una pagina HTML scrivo
<p class="testo">Testo del paragrafo</p>
perché il testo del paragrafo sarà bianco e non nero? Perché il selettore di classe prevale su quello di tipo con l'elemento?
Il primo concetto da imparare per avere una risposta è quello di peso. Si riferisce alla maggiore o minore importanza da assegnare a ciascuna regola. Un primo criterio di importanza è dato dall'origine del foglio di stile. Quando visualizziamo una pagina HTML possono entrare in gioco nel modificare lo stile degli elementi tre diversi fogli di stile:
- foglio dell'autore;
- foglio dell'utente;
- foglio predefinito del browser.
In ordine di importanza avremo: foglio dell'autore, foglio dell'utente, foglio predefinito del browser.
Tutti i browser web consentono una gestione di questo aspetto. È possibile, ad esempio, far sì che il browser ignori i CSS definiti dall'autore delle pagine e formattare queste ultime con un CSS realizzato dall'utente. E ancora, come vedremo, è possibile modificare questa gerarchia con l'uso della parola chiave !important
. Di base, però, l'ordine è quello definito qui sopra.
Specificità
La specificità, come il nome può suggerire, descrive il peso relativo delle varie regole all'interno di un foglio di stile. Esistono regole ben precise per calcolarla e sono quelle che applica un browser quando si trova davanti ad un CSS.
I fattori del calcolo sono tre e ciascuno di essi rappresenta il valore di una tripletta. Per prima cosa si conta il numero di selettori id
presenti nella regola. Si passa quindi a verificare la presenza di classi
e pseudo-classi
. Infine si conta il numero di elementi
definiti nella regola. Mai come in questo caso urge l'esempio. Prima regola:
#titolo {color: black;}
Calcolo: un id, 0 classi, 0 elementi. Tripletta dei valori: 1-0-0
Seconda regola:
.classe {background: #C00;}
0 id, una classe, 0 elementi. Tripletta: 0-1-0
Terza regola:
h1 {color: red;}
0 id, 0 classi, un elemento. Tripletta: 0-0-1
Il peso specifico della prima regola è il maggiore. Quello dell'ultima il minore. In pratica: gli id pesano più delle classi che pesano più dei singoli elementi. Non commettete l'errore di valutare il numero più grande a prescindere dalla sua posizione. La regola che segue presenta la specificità 1-0-0:
#paragrafo {color: green;}
ed è più importante di questa che ha i valori 0-0-2:
div p {color: red;}
Il concetto di cascata
Ed ora la summa di tutto quello cha abbiamo detto. Il concetto e il meccanismo della cascata spiegato con parole semplici. Tenteremo di ricostruire il procedimento di un browser quando incontra un foglio di stile e lo rende sul monitor del nostro computer.
- Per prima cosa controlla il target stabilito con l'attributo
media
o con dichiarazioni equivalenti. Scarta quindi tutti gli stili riferiti alla stampa o ad altri supporti. Allo stesso tempo scarta tutte le regole che non trovino corrispondenza negli elementi strutturali del documento. - Comincia ad ordinare per peso e origine secondo le regole viste sopra. C'è un CSS definito dall'autore? Userà quello. Altrimenti verificherà la presenza di un foglio di stile utente e in sua assenza applicherà le sue regole stilistiche predefinite.
- Quindi calcola la specificità dei selettori e in caso di conflitto tra regole usa questo criterio di prevalenza.
- Se non ci sono conflitti o se peso, origine e specificità coincidono, viene applicata la regola più vicina all'elemento nel codice del documento. L'ordine, se le dichiarazioni degli stili sono fatte nell'ordine più corretto e logico, è quindi il seguente: gli stili in linea prevalgono su quelli incorporati che a loro volta prevalgono su quelli collegati.
Importanza
Ed ora il concetto di importanza. Semplice e lineare la regola: se una dichiarazione viene accompagnata dalla parola chiave !important
essa balza al primo posto nell'ordine di applicazione a prescindere da peso, origine, specificità e ordine.