Frontend

Come usare le custom properties (variabili CSS)

Autore

Manuel Ricci

Da un po’ di tempo CSS ha introdotto le variabili, nome non ufficiale, perché quello vero è custom properties. Queste entità possono contenere un valore specifico che può essere riutilizzato all’interno del documento.

Siti molto complessi, ma anche applicazioni con una forte personalizzazione in termini di color palette hanno valori che vengono ripetuti centinaia di volte. Se dovessimo sostituire un valore perché al cliente non piace un colore o perché ha fatto un rebranding e quindi è necessario aggiornare la palette colori del sito dovremmo modificare centinaia di proprietà. Certo uno la può far semplice dicendo “Trova e sostituisci tutto e passa la paura”, sì, ma anche no. La situazione dove il trova e sostituisci non funziona è quella dove abbiamo usato lo stesso colore anche per altri elementi del design che però hanno senso con quel colore, immagino una tonalità di bianco, ad esempio. Sostituire tutto sarebbe un bel problema.

Questo scenario è uno dei tanti nella quale le custom properties di CSS risolvono non pochi grattacapi, un altro scenario che mi viene in mente è quello dove è possibile cambiare tema colore tra light e dark mode usando solo le variabili e non andando a riscrivere tutte le parti di CSS che ci servono aggiornate per il color scheme impostato.

Come si usano le custom properties CSS

Non sono un grande fan della notazione che si deve usare, ma le variabili CSS si dichiarano in questo modo: --nome-variabile: valore.

Per poterle usare si usano la funzione var(), in questo modo: var(--nome-variabile).

Nota bene che i due trattini all’inizio non fanno riferimento a metodologie particolari o best practice è proprio quella la sintassi da usare.

Altro nota bene è che le variabili funzionano solo per i valori delle proprietà, non per i nomi delle proprietà o per queries come le media o le container queries.

Il dove possiamo dichiarare una variabile CSS può avvenire in due punti:

  • All’interno di un qualunque blocco di dichiarazioni
  • Usando la pseudo classe :root

La differenza sostanziale tra i due punti è che il primo renderà disponibile la variabile solo nell’elemento selezionato e ai suoi figli, mentre nel secondo caso la proprietà sarà disponibile globalmente (ricorda che root è il tag <html>).

Vediamo quindi le due dichiarazioni:

1.mio-selettore {
2   --primary-bg-color: #b4d455;
3}

Oppure

1\:root {
2   --primary-bg-color: #b4d455;
3}

Ennesimo nota bene: i nomi delle variabili sono case sensitive. Ciò significa che --primary-bg-color è diverso da --primary-BG-color.

Per usare la custom properties dobbiamo quindi usare la funzione var() in questo modo.

1.mio-selettore {
2   --primary-bg-color: #b4d455;
3   background: var(--primary-bg-color);
4}
5
6/*Applicata ad un discendente di .mio-selettore*/
7.mio-selettore p {
8   background: var(--primary-bg-color);
9}

Ereditarietà delle custom properties CSS

Quando ad un elemento non ha un valore specificato per una custom properties per uno specifico elemento, viene usato il valore del genitore. Prendiamo in esame questo snippet di codice gentilmente offerto dalla documentazione di MDN.

1<div class="one">
2  <div class="two">
3    <div class="three"></div>
4    <div class="four"></div>
5  </div>
6</div>

Con il seguente CSS

1.two {
2  --test: 10px;
3}
4
5.three {
6  --test: 2em;
7}

I risultati di var(--test) saranno:

  • .two: 10px
  • .three: 2em
  • .four: 10px ereditato dal genitore
  • .one: invalid value, che è il valore di default di una proprietà personalizzata

Perché definirle variabili CSS non è del tutto corretto? Per farla breve non sono effettivamente variabili come si possono intendere in altri linguaggi di programmazione come, ad esempio, JavaScript. Il valore viene computato quando necessario e non viene memorizzato per essere usato altrove. La proprietà viene impostata per l’elemento selezionato e i suoi discendenti, come ogni altra cosa vista finora in CSS.

Valori di fallback

Può capitare, soprattutto nel caso si lavori con elementi personalizzati o con lo shadow DOM di aver necessità di impostare un valore di fallback di una variabile, cioè un valore che venga applicato qualora la variabile specificata non esistesse.

La funzione var() accetta un secondo parametro oltre al nome della variabile. Questo secondo parametro è proprio il valore di fallback. Ecco alcuni esempi

1.two {
2  background: var(--bg-color, #b4d455);
3}
4
5.three {
6  background: var(--bg-color, var(--primary-bg-color, #b4d455)); 
7}
  • Nel primo blocco se --bg-color non dovesse esistere allora verrà applicato #b4d455
  • Nel secondo blocco se --bg-color e --primary-bg-color non dovessero esistere allora verrà applicato #b4d455

Proprietà non validate o inesistenti

Come si comporta il browser in caso di proprietà non valide o inesistenti. Quando il browser rileva un valore non valido per una proprietà normale, scarta il valore e agli elementi vengono assegnati i valori che avrebbero avuto se la dichiarazione semplicemente non fosse mai stata scritta. Quando invece viene usata una proprietà personalizzata non sapendo dove verrà utilizzata la considera valida. Questo valore può essere utilizzato ovunque, anche dove non ha senso usarlo.

Qualora però questo valore non dovesse essere valido, allora in quel caso verranno usati i valori iniziali o ereditati della proprietà usata.

Supponiamo di avere un paragrafo e di applicare il seguente CSS:

1\:root {
2  --text-color: 16px;
3}
4
5p {
6  color: blue;
7}
8
9p {
10  color: var(--text-color);
11}

Che colore sarà il paragrafo?

Andiamo con ordine:

  1. Il browser sostituisce --text-color con 16px, ma non è una proprietà valida di color.
  2. Il browser quindi controlla se il valore di color è ereditabile. Lo è, ma il paragrafo non ha nessun genitore con la proprietà color impostata.
  3. Viene impostato il valore iniziale del paragrafo e cioè nero.

Caricamento...

Diventiamo amici di penna? ✒️

Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.

Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!

Ho in previsione di mandarti una newsletter ogni due settimane e una commerciale quando capita.