Come usare if() e else() nel CSS: esempi pratici e vantaggi della logica condizionale integrata

Per anni gli sviluppatori hanno lavorato all’interno dei confini ben definiti del CSS, apprezzandone la versatilità come linguaggio dichiarativo, ma consapevoli di un grande limite: l’assenza di una vera e propria logica condizionale nativa. La sua struttura, concepita per definire regole di stile in modo statico, specifico e ereditario, non offriva alcun meccanismo per implementare diramazioni logiche.

Questa situazione ha costretto sviluppatori e frontend engineer a cercare soluzioni alternative, affidandosi a preprocessori come SASS o LESS, oppure integrando direttamente JavaScript per gestire scenari dinamici e complessi. Sebbene efficaci, queste strategie hanno sempre rappresentato un compromesso, un workaround, che alla fine hanno introdotto dipendenze, aumentando la complessità del processo di build e allontanato la logica di presentazione dal foglio di stile a cui appartiene.

Oggi, questo scenario sta cambiando. L’introduzione delle regole condizionali if() ed else () nel CSS segna finalmente un punto di svolta.

Per la prima volta, gli sviluppatori hanno la possibilità di inserire la logica condizionale direttamente all’interno del valore di una singola proprietà CSS.

In questo articolo, esploreremo l’evoluzione del css, capiremo come funzionano le nuove regole condizionale fornendo esempi e casi pratici.

> Scopri anche la formazione in HTML e CSS

L’evoluzione del CSS verso soluzioni native

Tradizionalmente, gli sviluppatori utilizzano diverse tecniche per applicare stili in modo condizionale:

  • Media Queries (@media): permettono di applicare stili basati su caratteristiche del dispositivo o dell’ambiente di visualizzazione, come la larghezza dello schermo, l’orientamento o le preferenze dell’utente (ad esempio, il tema chiaro o scuro). L’uso delle media query implica la ripetizione di selettori e codice per diverse dimensioni dello schermo, soluzione che può risultare ridondante se si modifica una singola proprietà in più punti.
  • Feature Queries (@supports): conosciute anche come query di supporto, queste regole verificano se il browser supporta una specifica funzionalità CSS e applicano gli stili di conseguenza.
  • Utilizzo delle classi in HTML: Un metodo comune consiste nell’aggiungere o rimuovere dinamicamente classi agli elementi HTML (spesso tramite JavaScript) per alternare gli stili. Questo approccio poteva però portare a “inquinare” lo spazio dei nomi delle classi.
  • Variabili CSS personalizzate (*) e funzioni come calc(): l’introduzione di queste soluzioni ha reso il CSS più dinamico e capace di stili complessi e layout adattivi.
  • Preprocessori CSS (ad es. SASS): strumenti come SASS permettono di scrivere istruzioni condizionali (@if, @else) nei fogli di stile. Tuttavia, queste condizioni vengono elaborate in fase di compilazione, non in fase di esecuzione nel browser.

Nonostante siano state utili, queste tecniche sono un compromesso per emulare logiche condizionali CSS native in tempo reale.

I vantaggi di if() e else() nel css

La nuova funzione if() in CSS rende il CSS più dinamico e flessibile. Ecco i principali vantaggi:

  • Logica condizionale in-line per singole proprietà: a differenza delle @media o @supports query che avvolgono blocchi interi di codice CSS, la funzione if() consente di applicare stili condizionali direttamente all’interno del valore di una singola proprietà CSS. Questo significa poter definire più valori per una proprietà basati su diverse condizioni, come media query, support query o style query.
    • Esempio di Sintassi: Una proprietà può essere definita con property: if(condition-1: value-1; condition-2: value-2; else: value-4);. La funzione valuta le condizioni nell’ordine in cui appaiono e restituisce il valore associato alla prima condizione che risulta vera. Se nessuna condizione è soddisfatta, viene utilizzato il valore else (se presente).
  • Riduzione della ripetizione di codice: elimina la necessità di ripetere selettori e codice in più punti per modificare una singola proprietà in base a diverse condizioni. Ad esempio, per le media query, invece di avere diversi blocchi @media che modificano la stessa proprietà, si può usare un’unica if() per gestire tutti i breakpoint per quella proprietà.
  • Maggiore controllo con le style queries: la funzione style() all’interno di if() permette di eseguire query direttamente sul valore di una proprietà personalizzata CSS (variabile CSS) definita sull’elemento stesso. È inoltre possibile creare logiche più complessa utilizzando operatori logici come and, or, not all’interno delle style queries.
  • Integrazione con gli attributi HTML: la combinazione di if() con la funzione attr() (che consente di leggere i valori di qualsiasi attributo HTML, inclusi i data-attributes) è uno dei casi d’uso più significativi. Permette infatti di controllare gli stili dinamicamente basandosi sugli attributi HTML, facilitando la gestione dello stato dell’interfaccia utente (es. data-status="loading", data-status="error").
  • Creazione di breakpoint: è possibile definire variabili CSS personalizzate che rappresentano breakpoint (es. small, medium, large) e poi utilizzarle all’interno delle istruzioni if() per applicare stili diversi. Questo offre un modo per creare sistemi di tematizzazione più avanzati che vanno oltre le semplici modalità chiaro/scuro, supportando più di due stati o temi.
  • Riduzione della dipendenza da JavaScript: la logica condizionale nativa in CSS riduce la necessità di ricorrere a JavaScript per manipolare le classi o controllare le caratteristiche del browser per applicare stili. Questo permette di scrivere API dichiarative basate principalmente su HTML e CSS, contribuendo a siti e applicazioni più performanti e manutenibili.
  • Flessibilità e annidamento: La funzione if() può essere annidata all’interno di altre funzioni if() o di altre funzioni CSS come calc(). Può anche essere utilizzata per determinare parti di valori di proprietà, non solo valori interi. Consente inoltre di mescolare e abbinare diversi tipi di query (media, style, supports) all’interno della stessa funzione if() per creare una logica complessa.

Nonostante i suoi vantaggi, ricordiamo che if()è una tecnologia sperimentale e al momento è supportata solo in Chrome e Firefox, mentre gli altri browser stanno lavorando all’implementazione. Si consiglia quindi fornire valori di fallback per i browser non compatibili.

Esempi pratici e casi d’uso

Vediamo ora qualche caso pratico dell’utilizzo delle funzioni if() ed else(): proviamo, ad esempio, cambiare il colore di un elemento in base a determinate condizioni.

div {
    color: if(
                style(<condizione>): <valore>;
                style(<altra-condizione>): <altro-valore>;
                else: <valore-di-default>;
            );
}

Ad esempio, possiamo cambiare il colore di sfondo di un elemento in base al colore del testo.
Nel seguente esempio, se il colore del testo è bianco, il colore di sfondo sarà arancione, altrimenti sarà impostato il valore di default ‘transparent’.

div {
    color: var(--color);
    background-color: if(style(--color: #ffffff): #fb8b23;
            else: transparent);
}

.button-color:hover {
    --color: #fb8b23;
}

.button-color {
    --color: #ffffff;
}

In questo caso, se volessimo scrivere questo css in vanilla CSS, potremmo usare una classe per il colore di sfondo e un’altra per il colore del testo, come segue:

.button-color {
    background-color: #fb8b23;
    color: #ffffff;
}

.button-color:hover {
    background-color: transparent;
    color: #fb8b23;
}

In questo esempio, abbiamo definito una variabile CSS ‘–category’ che prende il valore dell’attributo ‘data-category’ dell’elemento. Poi, usiamo la funzione 'if()' per impostare il colore di sfondo, il colore del testo e il bordo in base al valore di questa variabile.

.box {
    --category: attr(data-category type(<custom-ident>));
    background-color: if (
        style(--category: cats): red;
        style(--category: dogs): blue;
        style(--category: fish): teal;
        else: green;
    );

    color: if (
        style(--category: cats): white;
        style(--category: dogs): white;
        style(--category: fish): cyan;
        else: black;
    );

    border: if (
        style(--category: cats): 1px solid white;
        style(--category: dogs): 1px solid white;
        style(--category: fish): 1px solid seafoam;
        else: 1px solid black;
    );
}

Se dovessimo scrivere questo CSS in vanilla CSS, potremmo usare le classi per ogni categoria, come segue:

.box { 
    background-color: green; 
    color: black;
    border: 1px solid black;
}

.box[data-category="cats"] { 
    background-color: red;
    color:white;
    border: 1px solid white;
}

.box[data-category="dogs"] { 
    background-color: blue;
    color: white;
    border: 1px solid white;
}

.box[data-category="fish"] { 
    background-color: teal;
    color: cyan;
    border: 1px solid white;
}

L’introduzione della funzione if() rappresenta più di una semplice aggiunta sintattica: apre una nuova prospettiva architetturale per chi sviluppa con CSS, permettendo di gestire condizioni e variabili direttamente nei fogli di stile senza dipendere da soluzioni esterne.
Con l’evoluzione di specifiche come le Style Queries e le potenzialità offerte dalle Range Queries, è realistico immaginare che in futuro sarà possibile valutare condizioni sempre più complesse all’interno di if(), rendendo il CSS uno strumento ancora più dinamico e adattabile. Inoltre, l’integrazione con le prossime proposte di funzioni personalizzate tramite @function promette di ampliare ulteriormente le possibilità del linguaggio, portandolo verso un modello di scrittura più espressivo, modulare e capace di gestire logiche complesse direttamente nel layer di presentazione.