Temi a colori con funzionalità CSS di base

David A. Herron
David A. Herron

Data di pubblicazione: 11 dicembre 2025

Quindi, hai un sito che vuoi creare o rinnovare. Magari hai in mente alcuni colori principali e stai pensando a come implementare rapidamente un tema basato su questi colori.

Avrai bisogno del colore principale, ma anche di colori per azioni, stati al passaggio del mouse, errori e altri elementi dell'interfaccia utente. E le opzioni per la modalità Luce e Buio? All'improvviso ti accorgi di aver bisogno di molti colori e la situazione può sembrare opprimente.

La buona notizia è che, quando si tratta di creare una tavolozza relativa ai token di colore che definiscono il tuo sito e di passare da una modalità di colore all'altra, le funzionalità di base possono fare gran parte del lavoro per te. Puoi esplorare alcune di queste tecniche nella demo in primo piano, una playlist a tema cromatico sul sito fittizio di Baseline Radio.

Creare una base con colori relativi

Se hai un'idea per un colore primario per il tuo tema, con alcune nozioni di base sulla teoria dei colori e la sintassi dei colori relativi CSS, puoi iniziare rapidamente a generare una tavolozza di colori da utilizzare nel tuo tema.

Supponiamo che il colore di base sia una tonalità di verde acqua, che puoi definire prima nel formato colore che preferisci. Puoi quindi utilizzare qualsiasi funzione di colore per creare nuovi colori rispetto al colore di base:

html {
  --base-color: oklch(43.7% 0.075 224);
}

La proprietà personalizzata --base-color viene creata utilizzando la funzione di colore oklch(). OkLCh è la forma cilindrica dello spazio colore Oklab e definisce i valori per tre canali: L (luminosità), C (croma), H (tonalità), più un canale alfa facoltativo per controllare la trasparenza.

OkLCh è un buon formato per questo tipo di manipolazione del colore, in quanto è progettato per fornire un'uniformità percettiva. Ad esempio, se modifichi solo la tonalità di un colore, il colore risultante dovrebbe avere una luminosità e una croma simili a quelle del colore originale. Ciò è particolarmente utile per evitare problemi di contrasto imprevisti.

Mantenendo la stessa luminosità e croma di --base-color, puoi regolare la tonalità di 120 gradi in entrambe le direzioni per una tavolozza triadica.

html {
  /* ... */
  --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  --triadic-color-secondary: oklch(from var(--base-color) l c calc(h - 120));
}

Come mostrato qui, la sintassi del colore relativo utilizza una funzione di colore che fa riferimento a un colore di origine (--base-color in questo esempio) con la parola chiave from e regola i rispettivi canali dello spazio colore in base al colore di output scelto, che in questo caso sarà anche OkLCh.

L'output risultante ti offre un rosa scuro per --accent-color e una tonalità di oro da utilizzare per --highlight-color, entrambi con la stessa luminosità e croma di --base-color originale.

html {
  /* ... */
  --accent-color: var(--triadic-color-primary);
  --highlight-color: var(--triadic-color-secondary);
}

  html {
    /* Input color in the rgb color space*/
    --base-color: teal;

     /* Output color in oklch. Computes to oklch(0.543123 0.0927099 314.769) */
     --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  }

Un colore complementare aggiungerebbe 180 gradi all'angolo di tonalità.

html {
  /* ... */
  --complement-color: oklch(from var(--base-color) l c calc(h + 180));
  --border-highlight: var(--complement-color);
}

Per uno stato al passaggio del mouse nell'interfaccia utente, potresti voler generare una versione più chiara di un determinato colore. Ciò significherebbe aumentare il valore del canale di luminosità. Per uno stato attivo, potresti voler aggiungere trasparenza regolando il canale alfa o oscurarlo diminuendo il valore del canale di luminosità.

html {
  /* Darken the --base-color by 15% */
  --base-color-darkened: oklch(from var(--base-color) calc(l * 0.85) c h);
  /* Assign this color a meaningful variable name */
  --action-color: var(--base-color-darkened);
  /* Lighten the --action-color by 15% */
  --action-color-light: oklch(from var(--action-color) calc(l * 1.15) c h);
  /* Darken the --action-color by 10% */
  --action-color-dark: oklch(from var(--action-color) calc(l * 0.9) c h);
}

Qui deriviamo il --action-color dal --base-color e lo utilizziamo per pulsanti e link. --action-color ha due varianti, più chiara e più scura, che si applicherebbero comunque anche se --action-color venisse modificato in modo da essere relativo a un altro colore diverso da --base-color.

Puoi regolare i canali utilizzando una funzione matematica come calc() o sostituendo completamente il canale con un nuovo valore. I canali invariati sono rappresentati dalle rispettive lettere (ad esempio, l per un valore di luminosità invariato).

Mescola i colori con color-mix()

Per altre varianti di colore, puoi adottare un approccio simile e modificare altri canali della proprietà personalizzata --base-color. In alternativa, utilizza color-mix() per aggiungere accenni del colore di base ad altri aspetti del design.

Il colore --border-color è una combinazione del colore di base e del colore denominato grey, interpolati nello spazio colore oklab. Se utilizzato come metodo di interpolazione del colore, fornisce risultati uniformi dal punto di vista percettivo.

html {
  --base-mix-grey-50: color-mix(in oklab, var(--base-color), grey);
  --border-color: var(--base-mix-grey-50);
}

Per impostazione predefinita, ogni colore è presente al 50%, ma puoi rendere un colore più o meno prominente regolando la relativa percentuale di ponderazione.

html {
  --background-mix-base-80: color-mix(in oklab,
    var(--background-color) 80%,
    var(--base-color));
  --surface-light: var(--background-mix-base-80);
}

Un'alternativa all'aggiunta di più colori a un elemento è la regolazione del relativo canale di croma utilizzando la sintassi relativa al colore. Il bordo degli input di testo nel modulo di contatto è leggermente più colorato quando è attivo.

[data-input*="text"] {
  --focus-ring: transparent;
  /* ... */
  &:focus {
    --focus-ring: oklch(from var(--border-color) l calc(c + 0.1) h);
  }
}

Attivare le modalità Luce e Buio

Una volta che hai un insieme di colori con cui lavorare, ti servirà un modo efficiente per applicare colori diversi per le modalità Chiaro e Buio.

Supporto dei temi chiaro e scuro per i segnali con la proprietà color-scheme

Puoi comunicare immediatamente al browser che il tuo sito può essere visualizzato in modalità "chiara", "scura" o in entrambe le modalità con la proprietà color-scheme. Questa proprietà indica al browser in quali schemi di colori un elemento può essere visualizzato comodamente.

 html {
   color-scheme: light dark;
}

Impostazione di color-scheme: light dark sullo pseudo-elemento :root o sull'elemento html:

  • Indica al browser che la pagina supporta la visualizzazione in modalità Luce o Buio.
  • Modifica i colori predefiniti dell'interfaccia utente del browser in modo che corrispondano all'impostazione del sistema operativo.

Per comunicare in anticipo agli user agent che la tua pagina supporta le modalità Chiaro e Scuro, puoi anche segnalare il supporto del cambio di combinazione di colori aggiungendo un elemento <meta> nel <head> del documento.

<head>
  <!-- ... -->
   <meta name="color-scheme" content="light dark">
</head>

Imposta le varianti "chiara" e "scura" con la funzione light-dark()

In qualità di autore, potresti essere abituato a impostare i colori di una pagina con una query prefers-color-scheme @media.

@media (prefers-color-scheme: light) {
  html {
    --background-color: oklch(95.5% 0 162);
    --text-color: black;
  }
}

@media (prefers-color-scheme: dark) {
  html {
    --background-color: oklch(22.635% 0.01351 291.83);
    --text-color: white;
  }
}

Questa soluzione è ideale per i colori e gli stili controllati dall'autore, ma, come accennato nella sezione precedente, dovrai comunque utilizzare color-scheme per aggiornare i colori dell'interfaccia utente del browser.

La modifica dei colori della pagina con una query prefers-color-scheme comporta anche una duplicazione del codice, poiché devi definire i colori per ogni modalità separatamente.

Con color-scheme impostato sulla pagina complessiva (o su elementi specifici), puoi utilizzare la funzione light-dark() per impostare i colori per ogni modalità in una riga di codice.

La funzione accetta due colori. Il primo viene utilizzato quando la combinazione di colori è impostata su "Chiaro", il secondo quando è impostata su "Scuro".

html {
  color-scheme: light dark;
  /* Color custom property values for both light and dark modes */
  --base-color: light-dark(oklch(43.7% 0.075 224), oklch(89.2% 0.069 224));
  --background-color: light-dark(oklch(95.5% 0 162), oklch(22.635% 0.01351 291.83));
  --accent-color: oklch(from var(--base-color) l c calc(h + 120));
  --active-color: light-dark(var(--action-color-light), var(--action-color-dark));
  /* ... */
}

Come per qualsiasi proprietà personalizzata, le impostazioni light-dark() per i colori possono essere impostate a livello globale o all'interno di componenti specifici e poi utilizzate altrove in base alle esigenze.

/* custom property usage */
body {
  background-color: var(--background-color);
  /* ... */
}

:any-link {
  /* ... */
  text-decoration-color: var(--accent-color);
}

Offrire agli utenti il controllo con lo switcher di temi integrato

È fantastico avere un tema che si adatta alle preferenze di colore predefinite del sistema o del browser di un utente, ma puoi fare un ulteriore passo avanti e dare ai visitatori del tuo sito la possibilità di ignorare queste preferenze di colore predefinite.

Se crei un pulsante di attivazione/disattivazione del tema che aggiorna l'attributo data-scheme dell'elemento <html>, puoi utilizzare lo stesso attributo per modificare color-scheme con CSS.

html {
  color-scheme: light dark;

  &[data-scheme="light"] {
    color-scheme: light;
  }

  &[data-scheme="dark"] {
    color-scheme: dark;
  }

  &[data-scheme="green"] {
      --base-color-light: oklch(48.052% 0.11875 151.945);
      --base-color-dark: oklch(92.124% 0.13356 151.558);
      color-scheme: light dark;
   }
}

data-scheme="light" e data-scheme="dark" mostrano la pagina solo nelle rispettive modalità di colore. data-scheme="green" può essere visualizzato in entrambe le modalità e cambia anche il --base-color in una tonalità di verde, il che ti offre una tavolozza completamente nuova, poiché la maggior parte degli altri colori si basa sul --base-color.

Registra le proprietà personalizzate con @property

Finora, i colori nella demo sono stati impostati come proprietà personalizzate standard. Puoi anche registrare le proprietà con la regola @property per usufruire dei vantaggi della verifica del tipo.

Poiché --base-color viene utilizzato come base di molti altri colori nell'interfaccia, è consigliabile assicurarsi che sia sempre un colore e che abbia un valore di riserva.

@property --base-color-light {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(43.7% 0.075 224);
}

@property --base-color-dark {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(89.2% 0.069 224);
}

html {
  --base-color: light-dark(var(--base-color-light), var(--base-color-dark));
}

In questo modo, se --base-color viene inavvertitamente modificato con un valore non valido, verrà sempre ripristinato il valore initial-value impostato con la regola @property.

La registrazione di determinate proprietà in questo modo consente anche di animare senza problemi i colori in un linear-gradient().

.main-heading {
  background: linear-gradient(in oklch 90deg, var(--text-color) 50%, oklch(from var(--base-color) l c var(--header-hue)));
  background-clip: text;
  color: transparent;
  animation: header-hue-switch 5s ease-in-out infinite alternate;
}

.main-heading ha uno sfondo linear-gradient() che viene mostrato attraverso il testo trasparente con la proprietà background-clip.

Una parte del testo mostra un hue che, utilizzando la sintassi del colore relativo, passa da un valore del canale di 26.67 a 277:

@keyframes header-hue-switch {
  from {
    --header-hue: 26.67;
  }

  to {
    --header-hue: 277;
  }
}

Con una proprietà personalizzata --header-hue registrata, questa animazione può avvenire senza problemi perché il browser sa che questa proprietà personalizzata è un numero.

@property --header-hue {
  syntax: '<number>';
  inherits: false;
  initial-value: 100;
}

Con una proprietà personalizzata non registrata, il browser non conoscerebbe il tipo di dati di --header-hue, quindi la transizione a un numero sarebbe un'animazione discreta, che passerebbe da uno stato all'altro senza interpolazione graduale.

Conclusione

I nuovi strumenti Baseline possono aiutarti a creare rapidamente una tavolozza di colori regolabile e a rendere più efficiente la creazione di variabili di colore. Tuttavia, dovrai comunque scegliere tra le infinite opzioni e combinazioni di colori.

La creazione dinamica della tavolozza in questo modo ti offre flessibilità. Se devi modificare il colore di base per il branding, puoi semplicemente aggiornare --base-color e il resto del tema verrà aggiornato di conseguenza. Oppure, se aggiungi funzionalità di riproduzione musicale, potresti decidere di cambiare dinamicamente il colore di base in modo che corrisponda al brano in riproduzione.

Crediti

Logica del selettore di temi adattata dal componente di cambio tema di Adam Argyle.