Creazione di una combinazione di colori

Una panoramica generale su come definire una combinazione di colori dinamica e configurabile

In questo post voglio condividere idee su come gestire più combinazioni di colori in CSS. Prova la demo.

Demo

Se preferisci i video, ecco una versione di YouTube di questo post:

Panoramica

Creeremo un sistema di colori accessibile con proprietà personalizzate e calc() per creare una pagina web che si adatti alle preferenze dell'utente e mantenere l'esperienza di creazione minima. Partiamo da un colore di base del brand e creiamo un sistema di varianti: 2 colori del testo, 4 colori di superficie e un'ombra corrispondente.

Questa guida inizia con la definizione iniziale di tutti i colori di ogni combinazione. Solo alla fine sono abituate a cambiare pagina.

Il brand

Spesso, un colore del brand è già stato definito e viene fornito come hex o gsuite. Questa GUI Challenge ha un colore di base del brand #0af. Innanzitutto, per questo sistema di colori, il valore esadecimale deve essere convertito in hsl.

* {
  --brand: #0af;
  --brand: hsl(200 100% 50%);
}

Per attivare il concetto di scurimento o schiarimento del colore del brand, ad esempio del 20%, è necessario estrarre i tre canali del valore del colore hsl nelle relative proprietà personalizzate, in questo modo:

* {
  --brand-hue: 200;
  --brand-saturation: 100%;
  --brand-lightness: 50%;
}

Il CSS può eseguire calcoli matematici sulle proprietà dei colori, ad esempio calc(var(--brand-lightness) - 20%) per ridurre il valore di luminosità del 20%. Si tratta di un aspetto fondamentale per la creazione di uno schema di colori, in quanto il CSS può mantenere tutti i colori nella stessa famiglia di tonalità regolando i livelli di saturazione e luminosità del file HTML.

Tema chiaro

Ogni variante di colore verrà contrassegnata con lo schema corrispondente e, in questo caso, a ciascuna viene aggiunto il carattere -light.

anteprima dei risultati finali con il tema chiaro

Brand

A partire dal colore del brand, viene ricreato unendo le proprietà personalizzate --brand-hue, --brand-saturation e --brand-lightness all'interno della parentesi della funzione hsl (), senza calcoli:

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}

Colori testo

In seguito, gli elementi essenziali di una combinazione di colori richiedono i colori del testo. In un tema chiaro, il testo dovrebbe essere molto scuro. Nota che la luminosità dei seguenti colori è bassa, ben inferiore al 50%.

* {
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
}

--text1-light, poiché è molto scura con una luminosità del 10%, mantiene l'elevata saturazione al 100% in modo che il colore del brand possa ancora spiccare nel blu marino scuro.

--text2-light, non è scuro come il primo colore, il che è buono in quanto è un colore secondario, ed è anche molto meno saturato.

Colori delle superfici

I colori delle superfici sono gli sfondi, i bordi e altre superfici decorative su cui si trova il testo o al suo interno. Nel tema chiaro si tratta dei colori chiari, a differenza di quelli del testo scuri. Per creare colori chiari con hsl, utilizzeremo valori percentuali più elevati nel terzo valore di luminosità. Riduce anche la saturazione, in modo che i grigi chiari non appaiano troppo colorati.

* {
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
}

Sono stati creati quattro colori di superficie poiché i colori decorativi tendono a richiedere più varianti, per momenti interattivi come :focus o :hover o per creare l'aspetto di strati di carta. In questi scenari è utile passare --surface2-light al passaggio del mouse su --surface3-light; in questo modo, il passaggio del mouse determina un aumento del contrasto (tra il 99% la luminosità e il 92% la luminosità; la luminosità diventa più scura).

Ombre

Le ombre di una combinazione di colori vanno oltre le aspettative, ma aggiungono un tocco di natura realistica all'effetto e lo fanno risaltare da ombre non realistiche basate su nero. A questo scopo, il colore dell'ombra utilizzerà la proprietà personalizzata della tonalità, sarà leggermente saturato con la tonalità ma sarà ancora molto scuro. Essenzialmente un'ombra molto scura leggermente blu.

* {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

--surface-shadow-light non è aggregato in una funzione hsl. Questo perché il valore --shadow-strength verrà combinato per creare una certa opacità e il CSS ha bisogno delle parti per eseguire i calcoli. Per saperne di più, passa alla sezione rad shadow.

Colori di luce combinati insieme

Non c'è bisogno di cercare in giro per scoprire come vengono realizzati i colori chiari, perché sono tutti in un unico posto nel CSS.

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
  --surface1-light: hsl(var(--brand-hue) 25% 90%);
  --surface2-light: hsl(var(--brand-hue) 20% 99%);
  --surface3-light: hsl(var(--brand-hue) 20% 92%);
  --surface4-light: hsl(var(--brand-hue) 20% 85%);
  --surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
  --shadow-strength-light: .02;
}
screenshot di tutti i colori della luce
Sandbox su CodePen

Tema scuro

La maggior parte dei brand non inizia con un tema scuro, ma una variante del tema principale, solitamente più chiaro. Gli utenti, invece, scelgono spesso un tema scuro per contesti diversi, ad esempio di notte. Questi fattori mi hanno portato a tenere a mente due aspetti sui temi scuri:

  1. In genere gli utenti non guardano i contenuti mentre utilizzano questo tema, quindi fai un test al buio.
  2. I colori dovrebbero scolorirsi per non vibrare sullo schermo perché sono troppo intensi.

anteprima del risultato finale del tema scuro

Brand

Il tema chiaro utilizzava i 3 valori dei canali colore HSL del brand senza alterazioni, il tema scuro no. La saturazione è dimezzata e la luminosità ha ridotto il 50% relativo.

* {
  --brand-dark: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 2)
    calc(var(--brand-lightness) / 1.5)
  );
}

Colori testo

In un tema scuro, i colori del testo devono essere chiari. I seguenti colori hanno valori elevati di leggerezza, che li avvicinano al bianco.

* {
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
}

Colori delle superfici

In un tema scuro, i colori della superficie devono essere scuri. I seguenti colori hanno bassa luminosità e saturazione, e la prima superficie è la più scura (10%).

* {
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
}

Ombre

In un tema scuro, le ombre possono essere molto difficili da vedere. Ha senso perché è difficile scurire qualcosa che è già abbastanza scuro. È qui che --shadow-strength-dark diventa molto utile, perché ci permette di scurire le ombre cambiando una variabile.

* {
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}

Guarda anche quanta saturazione c'è nell'ombra. Vedi il colore nell'interfaccia? Prova a rimuovere la saturazione da devtools, quale preferisci?

Colori scuri, tutti insieme

* {
  --brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
  --surface1-dark: hsl(var(--brand-hue) 10% 10%);
  --surface2-dark: hsl(var(--brand-hue) 10% 15%);
  --surface3-dark: hsl(var(--brand-hue) 5%  20%);
  --surface4-dark: hsl(var(--brand-hue) 5% 25%);
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}
screenshot di tutti i colori scuri
Sandbox su CodePen

Attenua il tema

Questa combinazione di colori è incentrata sull'orchestrazione di luminosità e saturazione. La saturazione dovrebbe essere sufficiente per mantenere comunque visibile una tonalità, ma dovrebbero anche superare appena i punteggi di contrasto perché sono pensati per essere comunque attenuati e con un contrasto basso.

anteprima dei risultati finali dal tema attenuato

Brand

* {
  --brand-dim: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 1.25)
    calc(var(--brand-lightness) / 1.25)
  );
}

Colori testo

* {
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
}

Colori delle superfici

* {
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
}

Ombre

* {
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}

Attenua tutti i colori insieme

* {
  --brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
  --text1-dim: hsl(var(--brand-hue) 15% 75%);
  --text2-dim: hsl(var(--brand-hue) 10% 61%);
  --surface1-dim: hsl(var(--brand-hue) 10% 20%);
  --surface2-dim: hsl(var(--brand-hue) 10% 25%);
  --surface3-dim: hsl(var(--brand-hue) 5%  30%);
  --surface4-dim: hsl(var(--brand-hue) 5% 35%);
  --surface-shadow-dim: var(--brand-hue) 30% 13%;
  --shadow-strength-dim: .2;
}
screenshot di tutti i colori attenuati
Sandbox su CodePen

Colori accessibili

Tieni presente che la luminosità più bassa nell'insieme di colori del testo scuro è pari al 65% e la luminosità massima nelle superfici scure è pari al 25%. ovvero il 40% di luce tra di loro. Nel tema chiaro, c'è il 55% di respiro nel tema chiaro. Mantenere una differenza di luminosità tra il colore del testo e quello della superficie circa il 40-50% può aiutare a mantenere alti i rapporti di contrasto dei colori, ma può anche essere una leva sottile per regolare in caso di punteggi bassi.

La chiamo "battere urto til ya pass", ovvero l'interazione di urtare il valore di luminosità finché uno strumento non mostra che sto passando.

Vengono premuti Maiusc + Freccia giù per abbassare la luminosità e aumentare il contrasto fino al passaggio

Ciascuno dei temi creati in questa sfida supera i punteggi di contrasto. La combinazione di colori attenuati ha il contrasto più basso, ma soddisfa comunque i requisiti minimi. Per aiutare gli altri membri del team a utilizzare colori a contrasto elevato, è consigliabile creare un nome di classe che accoppi il colore di superficie a un colore di testo accessibile.

.surface1 {
  background-color: var(--surface1);
  color: var(--text2);
}

.surface2 {
  background-color: var(--surface2);
  color: var(--text2);
}

.surface3 {
  background-color: var(--surface3);
  color: var(--text1);
}

.surface4 {
  background-color: var(--surface4);
  color: var(--text1);
}
Screenshot della superficie attenuata e degli abbinamenti di testo
Screenshot della superficie di attenuazione e accoppiamenti di messaggi con VisBug

Ombra Rad

I temi utilizzano una classe di utilità denominata .rad-shadow. Questa ombra è stata generata con lo strumento Ombra smussata, che apprezzo molto. Ho preso lo snippet generato e lo ho personalizzato con i miei colori e i miei calcoli di opacità. Il motivo è stato creare un'ombra che potevo regolare all'interno di ogni combinazione di colori.

tutte le ombre una accanto all'altra

A questo scopo, ho creato due variabili per ogni combinazione di colori da regolare: il colore dell'ombra e l'intensità dell'ombra. Il colore consente di regolare la saturazione e l'oscurità, mentre l'intensità rappresenta un modo semplice per aumentare l'intensità dell'ombra quando si tratta di una combinazione di colori scuri. Il risultato finale era qualcosa di simile a questo.

:root {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

.rad-shadow {
  box-shadow:
    0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
    0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
    0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
    0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
  ;
}

Se dovessi andare oltre le ombre nella mia combinazione di colori, renderei costanti gli angoli delle ombre, dato che la direzione della luce deve essere la stessa tra tutte le ombre del disegno.

Utilizzo delle combinazioni di colori

Dopo aver definito i colori predefiniti, è il momento di trasformarli in proprietà indipendenti dallo schema. In qualità di autore di CSS all'interno di questo progetto di combinazione di colori, raramente dovrebbe essere necessario accedere al valore di una combinazione di colori specifica. Voglio che sia semplice rimanere all'interno del tema.

A questo scopo, la combinazione di colori deve essere utilizzata esclusivamente tramite le proprietà personalizzate generiche, che definiremo a breve. In questo modo, gli utenti che utilizzano le variabili di progettazione non devono preoccuparsi della combinazione di colori attualmente impostata, devono solo utilizzare i colori di superficie e testo. Invece di color: var(--text1-light), usa color: var(--text1). L'adattamento e rotazione dei colori avviene a un livello molto più elevato nel CSS.

In dettaglio, gli stili connettivi del tema chiaro nel seguente blocco di codice connettono una proprietà personalizzata generica al colore specifico del tema chiaro. Ora tutti gli utilizzi di var(--brand) utilizzeranno il colore chiaro del brand.

Tema chiaro (automatico)

:root {
  color-scheme: light;
  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

Il sito ora utilizza il tema chiaro. È un momento di successo molto divertente! Esaminiamo alcuni di questi momenti in cui utilizziamo i nostri colori predefiniti in altri contesti.

Tema scuro (automatico)

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --brand: var(--brand-dark);
    --text1: var(--text1-dark);
    --text2: var(--text2-dark);
    --surface1: var(--surface1-dark);
    --surface2: var(--surface2-dark);
    --surface3: var(--surface3-dark);
    --surface4: var(--surface4-dark);
    --surface-shadow: var(--surface-shadow-dark);
    --shadow-strength: var(--shadow-strength-dark);
  }
}

Tema chiaro

[color-scheme="light"] {
  color-scheme: light;

  --brand: var(--brand-light);
  --text1: var(--text1-light);
  --text2: var(--text2-light);
  --surface1: var(--surface1-light);
  --surface2: var(--surface2-light);
  --surface3: var(--surface3-light);
  --surface4: var(--surface4-light);
  --surface-shadow: var(--surface-shadow-light);
  --shadow-strength: var(--shadow-strength-light);
}

Tema scuro

[color-scheme="dark"] {
  color-scheme: dark;

  --brand: var(--brand-dark);
  --text1: var(--text1-dark);
  --text2: var(--text2-dark);
  --surface1: var(--surface1-dark);
  --surface2: var(--surface2-dark);
  --surface3: var(--surface3-dark);
  --surface4: var(--surface4-dark);
  --surface-shadow: var(--surface-shadow-dark);
  --shadow-strength: var(--shadow-strength-dark);
}

Attenua il tema

[color-scheme="dim"] {
  color-scheme: dark;

  --brand: var(--brand-dim);
  --text1: var(--text1-dim);
  --text2: var(--text2-dim);
  --surface1: var(--surface1-dim);
  --surface2: var(--surface2-dim);
  --surface3: var(--surface3-dim);
  --surface4: var(--surface4-dim);
  --surface-shadow: var(--surface-shadow-dim);
  --shadow-strength: var(--shadow-strength-dim);
}

A questo punto, gli autori sono liberi di utilizzare le combinazioni di colori generiche fornite in base alle esigenze e non dovrebbero mai più preoccuparsi dei temi.

Conclusione

Ora che sai come ci sono riuscito, come faresti?! 🙂

Diversifica i nostri approcci e scopriamo tutti i modi per creare sul web. Crea un Codepen o ospita la tua demo, inviami un tweet e lo aggiungerò alla sezione Remix della community qui sotto.

Origine

Remix della community - @chris-kruining ha aggiunto un cursore per la tonalità, i colori di stato e le modalità di contrasto per no-preference, more e less: demo.