Vai al contenuto

Le funzioni array-mix() e linear-gradient() in CSS

Il CSS è nato come un linguaggio basato su un insieme di coppie proprietà-valore per uno o più elementi della pagina. Con l’evoluzione del CSS possiamo disporre di funzionalità più robuste, come variabili, formule matematiche, logica condizionale e una serie di nuovi pseudo-selettori, solo per citarne alcuni. Possiamo anche utilizzare CSS per creare un array. Più precisamente, possiamo creare una serie di colori partendo da una funzione che è stata introdotta recentemente.

La funzione color-mix() è un’aggiunta alle specifiche CSS Color Module Level 5. Il suo scopo principale è fondere due o più colori insieme, generando un nuovo colore in base a rapporti specificati. Il processo di fusione dipende dallo spazio colore in cui i colori vengono combinati.

La funzione color-mix()

La sintassi della color-mix()funzione è la seguente:

color-mix(<colorspace>, <color> <percentage>, <color> <percentage>, ...);

dove:

  • <colorspace>: lo spazio colore in cui avverrà la fusione. Può essere uno dei seguenti: srgb, display-p3, labo lch.
  • <color>: I colori da miscelare tra loro. Questi possono essere specificati utilizzando vari modelli di colore, come RGB, HSL o LCH.
  • <percentage>: il peso di ciascun colore nella miscela. La somma di tutte le percentuali deve essere pari al 100%.

Ad esempio:

:root {
  --cm-color-rosso: rgb(255, 0, 0);
  --cm-color-blu: rgb(0, 0, 255);
}

.rgb-srgb-mix {
  background-color: color-mix(
    srgb,
    var(--cm-color-rosso) 50%,
    var(--cm-color-blu) 50%
  );
}

Uno spazio colore è un’organizzazione specifica dei colori che consente rappresentazioni riproducibili dei colori sia su supporti digitali che fisici. Esistono diversi spazi colore utilizzati nel web design, ognuno con le sue caratteristiche uniche:

  • RGB : lo spazio colore Rosso-Verde-Blu è un modello di colore additivo in cui la luce rossa, verde e blu viene combinata in vari modi per produrre un’ampia gamma di colori. È lo spazio colore più comunemente utilizzato per le immagini digitali e il web design.
  • HSL : lo spazio colore Tonalità-Saturazione-Luminosità rappresenta i colori utilizzando tre componenti: tonalità, saturazione e luminosità. Questo modello di colore è progettato per essere più intuitivo e percettivamente rilevante rispetto al modello RGB.
  • LCH : lo spazio colore Leggerezza-Croma-Tonalità è una rappresentazione cilindrica dello spazio colore CIELAB, progettato per essere percettivamente uniforme. LCH mira a fornire una rappresentazione più accurata di come gli esseri umani percepiscono le differenze di colore.
  • sRGB : lo spazio colore standard Rosso-Verde-Blu è uno spazio colore RGB ampiamente utilizzato che fornisce una riproduzione del colore coerente su vari dispositivi e piattaforme.

Costruire la ruota dei colori lineare è un altro esempio delle potenzialità della funzione color-mix(). Spesso è utile quando si sperimenta una nuova funzionalità sapere già quale dovrebbe essere il risultato visivo.

Primo: definire i colori primari di base.

--primary-1: #ff0; 
--primary-2: #f00; 
--primary-3: #00f;

Successivo: mescola i colori primari per creare i colori secondari.

--secondary-1: color-mix(in srgb, var(--primary-1) 50%, var(--primary-2)); 
--secondary-2: color-mix(in srgb, var(--primary-2) 50%, var(--primary-3)); 
--secondary-3: color-mix(in srgb, var(--primary-3) 50%, var(--primary-1));

La color-mix() supporta l’utilizzo di diversi spazi colore, quindi possiamo sperimentare altri spazi colore sostituendo l’uso di srgb nell’esempio precedente per vedere come cambia la ruota dei colori. La color-mix() non si limita alla combinazione di codici HEX. Possiamo mescolare più tipi di colore contemporaneamente. L’esempio precedente può essere modificato per utilizzare diversi tipi di colore restituendo gli stessi risultati.

--primary-1: yellow; 
--primary-2: rgb(255,0,0); 
--primary-3: hsl(240,100%,50%);

e cosi via…

La definizione di color-mix dice che la funzione accetta due valori <color> e restituisce il risultato della loro miscelazione in un dato spazio colore per una determinata quantità. Il trucco, quindi, sta nel non utilizzarlo per lo scopo previsto, ovvero mescolare i colori, ma nell’utilizzarlo invece per restituire uno dei due colori nell’elenco degli argomenti.

:root { 
  --colors: black, white; /* define an array of color values */ 
  --i: 1; 
  --_color: color-mix(in hsl, var(--colors) calc(var(--i) * 100%)); 
} 

body { 
  background-color: var(--_color); 
}
Dopo aver definito in –colors i due colori e una variabile –i che sarà il nostro indice, per selezionare i colori bisognerà semplicemente cambiare l’indice da 0 a 1 e viceversa. A conti fatti, il codice che appare tanto complesso, sostituendo i valori dove richiesto, assumerebbe questo aspetto (quando la –i=0):
--_color: color-mix(in hsl, black, white 0%);

Ovviamente il primo parametro, cioè lo spazio di colori scelto (HSL), in questo caso è ininfluente perchè non stiamo mescolando colori.

Tuttavia possiamo già cosi, definendo più variabili, creare una palette di sfumature tra due colori. Nelle’esempio successivo creiamo una classe .div che applicheremo a un elemento HTML div, e poi attraverso l’attributo style, modificando opportunamente la variabile –i, potremo creare diverse sfumature tra i due colori:

.div { 
  --colors: black, white; /* define an array of color values */ 
  --i: 0; 
  --_color: color-mix(in srgb, var(--colors) calc(var(--i) * 100%)); 
  background-color: var(--_color); 
  width: 200px;
  height: 200px;
}

<div class="div" style="--i:0.4">
</div>

In questo modo stiamo dicendo di voler impostare il 40% del secondo colore definito in –color. Attenzione sempre allo spazio di colore utilizzato, perchè i risultati potrebbero essere imprevisti.

Utilizzare la color-mix() può migliorare significativamente il processo di progettazione e offre vari vantaggi:

  1. Manipolazione dinamica del colore: consente ai progettisti di creare un’ampia gamma di variazioni di colore basate su token di colore predefiniti. Questa flessibilità semplifica la gestione e la regolazione dei colori all’interno del sistema di progettazione, riducendo la necessità di regolazioni manuali dei colori.
  2. Temi colore adattivi : può essere utilizzata per generare temi colore che si adattano a diversi contesti, come le modalità chiaro e scuro, fondendo i colori di base con rapporti variabili. Questa adattabilità semplifica la creazione di progetti sensibili al contesto e garantisce coerenza visiva tra ambienti diversi.
  3. Coerenza del colore migliorata: garantisce la coerenza in tutto il sistema di progettazione, poiché i colori derivano da una serie di token predefiniti. Questa coerenza rende più semplice per i progettisti mantenere un linguaggio visivo coerente durante tutto il progetto.
  4. Esplorazione efficiente del colore: consente ai designer di esplorare rapidamente varie combinazioni di colori e trovare l’equilibrio perfetto per i loro progetti. Questa efficienza riduce il tempo dedicato a tentativi ed errori, consentendo ai progettisti di concentrarsi su altri aspetti del processo di progettazione.
  5. Collaborazione più semplice: i designer possono condividere e collaborare sulle combinazioni di colori in modo più efficace. Questa integrazione promuove un approccio unificato alla gestione del colore e aiuta a mantenere la coerenza visiva tra progetti su larga scala che coinvolgono più designer.

Uso di più colori con linear-gradient()

Il trucchetto visto sopra funziona solo per 2 colori. Purtroppo aggiungendo a –color un terzo colore, la funzione non ritornerà nessun colore. Come possiamo ovviare allora a questo problema?

Sostituiamo la color-mix con la funzione linear-gradient(). In questo caso possiamo estendere la variabile –color definendo 2 o più colori. Vediamo quest’altro esempio:

.box { 
  --colors: red, blue, green, yellow; 
  background: linear-gradient(--colors); 
}

In questo caso abbiamo creato una classe “box” che applicheremo ad un elemento HTML div. Il risultato sarà un gradiente creato a partire con i 4 colori definiti in –color.

Adesso sostituiamo l’ultima riga in questo modo e aggiungiamo due variabili che rappresentano l’indice del colore corrente e il numero totale dei colori presenti in –color:

.box {
  --colors: red, blue, green, yellow;
  --n: 4;
  --i: 0;
  background: linear-gradient(var(--colors)) no-repeat 0 calc(var(--i)*100%/(var(--n) - 1)) /100% calc(1px*infinity);
}

<div class="box" style="--i:1">test</div>
<div class="box" style="--i:3">test</div>

Questo è un approccio molto “hacking”: dopo aver applicato la classe box a due div, possiamo impostare la variabile –i attraverso l’uso dell’attributo style, in modo tale da scegliere il colore attraverso il suo indice corrispondente nella variabile “array” –colors.

Mentre il metodo visto prima con array-mix è considerato sicuro perchè si basa sull’uso di due soli colori, questo con linear-gradient potrebbe portare a risultati imprevisti,  a un ritardo delle prestazioni o, peggio, a problemi di accessibilità. Un’altra limitazione è che questo trucchetto può essere utilizzato solo con la proprietà background. Potremmo superare questo problema con altri trucchi, come usare background-clip: text per manipolare il colore del testo. Ma poiché questo utilizza gradienti, che sono supportati solo da proprietà specifiche, l’utilizzo è limitato.