CSS Custom Properties
CSS Custom Properties
Extrowebsite

Le Custom Properties, altrimenti chiamate CSS Variables, consentono di introdurre le variabili nelle dichiarazioni CSS. Al pari delle , istruzioni condizionali CSS, mettono in campo un costrutto che avvicina molto la sintassi dei fogli di stile a quella dei maggiori pre-processori CSS, quali LESS oppure SASS.

Come è ormai noto, la maggior parte dei linguaggi di programmazione si basa sulle variabili. Da qualche tempo, tra questi linguaggi, si devono inserire anche i CSS. I fogli di stile a cascata, visti come linguaggio di programmazione, stanno prendendo sempre più piede. I CSS sono nati per formattare le pagine web mentre oggi è possibile, tra le altre cose, fare anche calcoli matematici.

I CSS, purtroppo, sin dalle origini non hanno avuto il supporto per le variabili. Chi scrive codice CSS deve affidarsi a pre-processori, come scritto nella intro, come LESS, SASS ed altri ancora.

Potrebbe rappresentare un problema, quando si inizia a lavorare con un pre-processore, o framework, il fatto che si deve necessariamente imparare una nuova sintassi. Ogni pre-processore richiede un modo diverso di dichiarare le variabili. Solitamente la dichiarazione di una variabile inizia con un simbolo riservato. Per esempio: $ in Sass e @ in LESS.

Fortunatamente, il W3C ha rilasciato a livello di Candidate Recommendation, il CSS Custom Properties for Cascading Variables Module Level 1.

Finalmente si può affermare che anche i CSS supportano le variabili.

Supporto delle CSS Custom Properties da parte dei browser

Prima di vedere come funzionano le Variabili CSS, sarebbe bene dare uno sguardo al loro supporto da parte dei browsers. Di seguito, nell'immagine, è riportato il grafico ripreso da Can I Use, al momento della scrittura del seguente articolo.

Supporto CSS Custom Properties Can I Use
Supporto CSS Custom Properties nei browsers

A vedere l'immagine si può asserire che le Custom Properties possono essere tranquillamente utilizzate nei siti di produzione. Con una percentuale prossima all'88% e con il supporto da parte dei maggiori browsers, si dovrebbe essere abbastanza fiduciosi nell'adottare tali dichiarazioni nei fogli di stile.

Perchè le Variabili CSS sono importanti

Se si è nuovi nell'utilizzo delle variabili o se con i CSS si lavora già da tempo, di seguito vengono illustrati alcuni motivi per cui iniziare ad usarle o continuare a lavorare con esse.

  1. Codice CSS più leggibile. Senza tanti giri di parole si può affermare che, lavorando con le Variabili CSS, il codice è immediatamente leggibile, individuabile e manutenibile.
  2. Facilità di modifica in documenti di grandi dimensioni. Se tutte le costanti sono state salvate in un file separato, non è necessario scorrere migliaia di righe di codice quando si desidera apportare una modifica ad una variabile. E' sufficiente cambiare un valore per vedere immediatamente applicata la modifica.
  3. Individuare gli errori più velocemente. E' una grandissima perdita di tempo dover cercare codice tra le righe per individuare un errore. La cosa ancora più grave se questo errore fosse dovuto a un semplice refuso. L'utilizzo delle Variabili CSS elimina questi problemi.

Definire le Variabili CSS

Nei CSS, una variabile è una qualsiasi "proprietà" il cui nome inizia con due trattini (dash dash in inglese).

div {
--color:#000;
}

La variabile, nel blocco di codice appena scritto, appare regolarmente nella posizione di una proprietà. La si contraddistingue immediatamente in quanto è preceduta dai due trattini (--).

Riferendoci al blocco di codice precedente, la variabile --color:#000 indica il colore di testo di un ipotetico elemento di blocco div.

Ambito globale e locale delle Variabili CSS

Focalizziamo l'attenzione su un punto molto importante. Si prenda un linguaggio di programmazione tra i più conosciuti, per esempio JavaScript. In esso le variabili hanno un ambito. Possono avere un ambito globale o ambito locale.

La stessa cosa accade con le Variabili CSS.

Si veda l'esempio qui di seguito:

:root {
  --primary-color: red;
}

Il selettore :root consente di targetizzare l'elemento di livello più alto nel DOM o nell'albero del documento. Questo sta ad indicare che le variabili dichiarate in questo modo sono da intendersi in ambito globale.

Si veda un esempio molto semplice. In un file HTML, si scriva la seguente dichiarazione CSS nella <head>:

:root {
  --primary-color: blue;
}

p {
color: var(--primary-color);
}

Se nel <body> ci sono uno o più paragrafi, tutti sarebbero di colore blue.

In questo caso, il colore assegnato al selettore :root, attraverso la variabile --primary-color, assume un ambito globale. Questo vuol dire che se nessun altro colore di testo viene dichiarato a livello di CSS, TUTTI i testi del sito, racchiusi all'interno dei paragrafi, saranno di colore blue se fanno riferimento alla variabile --primary-color.

Una volta che una variabile è stata definita e le è stato assegnato un valore, è possibile riutilizzarla tante volte come valore di una proprietà.

Chi lavora con i pre-processori, è abituato ad usare una variabile facendo riferimento al suo nome. Per esempio:

$font-size: 18px;

div {
font-size: $font-size;
}

Con le Variabili CSS, le cose sono diverse. Si fa riferimento ad una variabile usando la funzione var().

Tornando al blocco di codice CSS inerente il colore di testo blue, si noti come viene assegnata la variabile all'elemento p.

p {
color: var(--primary-color);
}

Ricapitolando. Viene definita prima la variabile a livello globale:

:root {
  --primary-color: blue;
}

Successivamente la stessa variabile viene assegnata all'elemento p attraverso la funzione var().

p {
color: var(--primary-color);
}

Apparentemente potrebbe sembrare un argomento ostico, ma non è così.

Si veda adesso un esempio di variabile a livello locale.

Prendendo come esempio il colore di testo di una pagina HTML abbiamo:

:root {
  --primary-color: blue;
}

.box {
--primary-color: red;
color: var(--primary-color);
}

Notare che il nome delle variabili, sia a livello globale che a livello locale, è uguale: --primary-color.

Se a livello globale il colore assegnato al testo è blue, a livello locale, in presenza di variabili con lo stesso nome, il colore dichiarato per il testo è red. Di conseguenza, di quale colore sarà il testo all'interno di un elemento con classe .box? Ovviamente red, rosso.

Questo succede perchè a livello locale, è stata dichiarata una variabile più specifica, che va a sovrascrivere quella a livello globale.

Se prima o dopo un elemento con classe .box volessimo un paragrafo al quale non viene assegnata alcuna classe, di quale colore sarà il testo? Il testo avrà il colore di default del browser: nero, in quanto non è stata presa in considerazione nè la variabile globale ( --primary-color: blue; ), nè quella a livello locale ( --primary-color: red; ).

Si noti come il comportamento dei fogli di stile, con l'introduzione delle variabili, è identico a quello "classico".

Dopo aver messo un punto fermo tra ambito globale ed ambito locale delle variabili, vediamo alcune proprietà molto importanti.

Le Custom Properties sono proprietà ordinarie. Possono essere dichiarate per qualsiasi elemento. Paragrafo, sezione, aside, root ed anche per pseudo elementi CSS. Funzioneranno come è sempre avvenuto e come ci si aspetta.

p {
--color: aqua;
}

p:before {
--font-size: 20px;
}

section {
--color: green;
}

:root {
--margin: 1em;
}

Le Variabili CSS rispettano tutte le regole di ereditarietà e cascata. Si veda il blocco di codice di seguito:

* {
--color-text: blue;
}

div {
color: var(--color-text);
}

.one {
--color-text: red;
color: var(--color-text);
}

.two {
color: var(--color-text);
}

Il codice CSS apre con il selettore universale (*) nel quale viene dichiarata la variabile --color-text. A tale variabile viene assegnato il valore blue. Stando a questa prima dichiarazione, tutti i testi sarebbero blue se facessero riferimento alla variabile, attraverso la funzione var.

Infatti, il primo e terzo div avranno il testo di colore blue. Il secondo, invece, avrà il testo di colore rosso. Questo perchè, nonostante sia stata dichiarata ed assegnata la variabile con lo stesso ed identico nome, assume un valore più specifico in quanto si riferisce al div la cui classe è .one. Come scritto precedentemente, la specificità della variabile in ambito locale sovrascrive quella dichiarata in ambito globale.

Nel blocco di codice riportato qui sopra sono evidenti i comportamenti normalissimi dei fogli di stile:

  1. ereditarietà e cascata
  2. specificità

Ereditarietà: perchè nel selettore universale è stata scritta una determinata dichiarazione.

Specificità: perchè nel secondo div è stata scritta una dichiarazione ancora più specifica e che si riferisce solo e soltanto a tutti gli elementi con classe .one.

Riferendoci sempre al blocco di codice appena visto, ha senso introdurre le Custom Properties?

No, se trattasi di 3 righe di codice. Si, invece, se abbiamo un intero sito all'interno del quale ci sono decine e decine di dichiarazioni CSS che possono essere accorpate in una. Pensiamo, ad esempio, ai margini, al padding, al colore del testo, al colore dei link ecc.

Le variabili CSS possono essere utilizzate con le regole @media condizionali.

Come accade con le altre proprietà, è possibile modificare il valore di una variabile CSS all'interno di un blocco @media o di altre regole condizionali.

Ad esempio, il codice seguente attribuisce valori differenti a seconda della dimensione del viewport.

:root {
--padding: 20px;
}

@media screen and (min-width:768px) {
--padding: 30px;
}

Le variabili CSS possono essere utilizzate direttamente nell'HTML.

E' possibile impostare il valore delle variabili in linea per stilizzare un elemento, ed il risultato sarà come previsto.

<!--HTML-->
<html style="--color: blue">

<!--CSS-->
body {
color: var(--color)
}

Le Variabili CSS sono case-sensitive.

Porre attenzione a questo aspetto non di poco conto. Se si pensa che scrivere una dichiarazione in maiuscolo o minuscolo sia la stessa cosa, si sbaglia.

p {
--color: green;
--COLOR: green;
}

Il codice appena scritto introduce e dichiara due variabili distinte e separate.

  1. --color
  2. --COLOR

non sono la stessa cosa.

Dichiarazioni di variabili CSS non valide

Potrebbe darsi il caso che in fase di dichiarazione di variabili, a queste venga assegnato un valore non valido. Gli errori di sintassi non vengono presi in considerazione e le funzioni var() non valide vengono sostituite ed impostate automaticamente sul valore iniziale o ereditato della proprietà in questione. Vediamo due esempi per spiegare meglio quanto appena scritto.

:root { --color: 16px; }
p { background-color: red; }
p { background-color: var(--color); }

Nella prima dichiarazione è stato assegnato un valore (16px) alla variabile --color.
Immediatamente sotto abbiamo un elemento paragrafo con colore di sfondo rosso.
Nell'ultima dichiarazione ci si aspetta che il colore di background assegnato sostituisca il secondo, ma questa contiene un valore errato in quanto:

p { background-color: 16px; }

è un valore NON VALIDO. In questo caso background-color non è una proprietà ereditabile, il valore verrà impostato automaticamente sul suo valore iniziale, cioè transparent.

Effettivamente, se si provasse a scrivere il codice CSS come è stato proposto e nella pagina HTML abbiamo due paragrafi, ad essi non verrà assegnato nessun colore di sfondo.

Se, invece, abbiamo:

:root { --color: 16px; }
p { background-color: var(--color); }
p { background-color: red; }

in questo caso l'ultima dichiarazione

p { background-color: red; }

sostituisce la seconda ed otterremo tutti i paragrafi presenti nella pagina con colore di background dichiarato: rosso.

Vediamo ancora una casistica che potrebbe essere degna di menzione.

E' importante prestare attenzione quando si scrivono dichiarazioni con le variabili CSS. Si veda il codice seguente:

font-size: 16px

Quando si imposta il valore di una proprietà, come si è appena visto, il valore "16px" viene interpretato come una singola entità.

Si veda adesso il seguente codice:

:root {
--font-size: 16
}

p {
font-size: var(--font-size)px
}

Se si pensa che la dimensione del font sia 16px, è sbagliato. Il browser interpreta quella dichiarazione come 16 px. Da notare lo spazio tra 16 e px.

Conclusioni

Al termine di questo articolo, nel quale è stato introdotto qualche codice di esempio, spero si siano visti i vantaggi per cui utilizzare le CSS Custom Properties. E' stata accennata la differenza tra le variabili di un pre-processore e le variabili CSS native. Anche se il modulo CSS Custom Properties for Cascading Variables Level 1 è stato rilasciato un po' di tempo fa, oggi si può dire che entra a pieno titolo a far parte del codice CSS per un sito in produzione, visto il supporto da parte dei browser più moderni.