Miglioramento dello stile predefinito della modalità Buio con la proprietà CSS color-scheme e il meta tag corrispondente

La proprietà CSS color-scheme e il meta tag corrispondente consentono agli sviluppatori di attivare per le loro pagine i valori predefiniti specifici per il tema del foglio di stile dello user agent.

Contesto

La funzionalità multimediale preferenze utente di prefers-color-scheme

La funzionalità multimediale delle preferenze dell'utente di prefers-color-scheme offre agli sviluppatori il controllo completo sull'aspetto delle loro pagine. Se non lo conosci, leggi il mio articolo prefers-color-scheme: Hello darkness, my old friends, in cui ho documentato tutto quello che so sulla creazione di fantastiche esperienze con la modalità Buio.

Un pezzo del puzzle menzionato solo brevemente nell'articolo è la proprietà CSS color-scheme e l'omonimo meta tag corrispondente. Entrambi semplificano la vita di sviluppatore consentendoti di attivare per la tua pagina valori predefiniti specifici per tema del foglio di stile dello user agent, come ad esempio i controlli del modulo, le barre di scorrimento e i colori di sistema CSS. Allo stesso tempo, questa funzionalità impedisce ai browser di applicare autonomamente qualsiasi trasformazione.

Supporto del browser

prefers-color-scheme

Supporto dei browser

  • 76
  • 79
  • 67
  • 12.1

Origine

color-scheme

Supporto dei browser

  • 81
  • 81
  • 96
  • 13

Origine

Il foglio di stile dello user agent

Prima di continuare, vediamo brevemente cos'è un foglio di stile dello user agent. Nella maggior parte dei casi, puoi pensare alla parola user agent (UA) come a un modo stravagante per definire browser. Il foglio di stile UA determina l'aspetto predefinito di una pagina. Come suggerisce il nome, un foglio di stile UA è qualcosa che dipende dalla UA in questione. Puoi dare un'occhiata al foglio di stile UA di Chrome (e di Chromium) e confrontarlo con quello di Firefox o di Safari (e di WebKit). In genere, i fogli di stile UA concordano sulla maggior parte delle cose. Ad esempio, rendono i link blu, il testo generico nero e il colore di sfondo bianco, ma esistono anche differenze importanti (e a volte fastidiose), ad esempio lo stile dei controlli del modulo.

Dai un'occhiata più da vicino al foglio di stile UA di WebKit e al funzionamento della modalità Buio. Esegui una ricerca a testo intero della parola "scuro" nel foglio di stile. Il valore predefinito fornito nel foglio di stile cambia a seconda che la modalità Buio sia attiva o meno. Per illustrarlo, ecco una regola CSS che utilizza la pseudoclasse :matches e le variabili interne WebKit come -apple-system-control-background, nonché la direttiva del preprocessore interno WebKit #if defined:

input,
input:matches([type="password"], [type="search"]) {
  -webkit-appearance: textfield;
  #if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
      HAVE_OS_DARK_MODE_SUPPORT
    color: text;
    background-color: -apple-system-control-background;
  #else
    background-color: white;
  #endif
  /* snip */
}

Noterai alcuni valori non standard per le proprietà color e background-color riportate sopra. Né text-apple-system-control-background sono colori CSS validi. Sono colori semantici interni a WebKit.

È emerso che CSS ha colori di sistema semantico standardizzati. Sono specificati nel livello 4 del modulo colore CSS. Ad esempio, Canvas (da non confondere con il tag <canvas>) serve per lo sfondo dei contenuti o dei documenti dell'applicazione, mentre CanvasText si riferisce al testo nei contenuti o nei documenti dell'applicazione. I due tipi sono collegati e non devono essere usati in modo isolato.

I fogli di stile UA possono utilizzare colori proprietari o standard del sistema semantico per determinare come il rendering degli elementi HTML deve essere eseguito per impostazione predefinita. Se il sistema operativo è impostato sulla modalità Buio o utilizza un tema scuro, CanvasText (o text) viene impostato sul bianco in modo condizionale, mentre Canvas (o -apple-system-control-background) viene impostato sul nero. Il foglio di stile UA assegna quindi il seguente CSS una sola volta e copre sia la modalità Luce sia la modalità Buio.

/**
  Not actual UA stylesheet code.
  For illustrative purposes only.
*/
body {
  color: CanvasText;
  background-color: Canvas
}

La proprietà CSS color-scheme

La specifica Livello 1 del modulo di regolazione del colore CSS introduce un modello e dei controlli sulla regolazione automatica del colore da parte dello user agent con l'obiettivo di gestire le preferenze dell'utente, come la modalità Buio, la regolazione del contrasto o le specifiche combinazioni di colori desiderate.

La proprietà color-scheme definita al suo interno consente a un elemento di indicare le combinazioni di colori per il rendering. Questi valori vengono negoziati in base alle preferenze dell'utente, il che genera una combinazione di colori scelta che influisce su elementi dell'interfaccia utente (UI), ad esempio i colori predefiniti dei controlli del modulo e delle barre di scorrimento, nonché sui valori utilizzati dei colori di sistema CSS. Attualmente sono supportati i seguenti valori:

  • normal Indica che l'elemento non è a conoscenza delle combinazioni di colori, quindi l'elemento deve essere visualizzato con la combinazione di colori predefinita del browser.

  • [ light | dark ]+ Indica che l'elemento è a conoscenza delle combinazioni di colori elencate e può gestirle ed esprime una preferenza ordinata tra di esse.

In questo elenco, light rappresenta una combinazione di colori chiari con colori di sfondo chiari e colori in primo piano scuri, mentre dark rappresenta il contrario, con colori di sfondo scuri e colori in primo piano chiari.

Per tutti gli elementi, il rendering con una combinazione di colori dovrebbe far corrispondere i colori utilizzati in tutte le UI fornite dal browser affinché l'elemento corrisponda all'intento della combinazione di colori. Alcuni esempi sono le barre di scorrimento, le sottolineature per il controllo ortografico, i controlli del modulo e così via.

Nell'elemento :root, il rendering con una combinazione di colori deve inoltre influire sul colore della superficie del canvas (ovvero il colore di sfondo globale), sul valore iniziale della proprietà color e sui valori utilizzati dei colori di sistema. Inoltre, deve influire sulle barre di scorrimento dell'area visibile.

/*
  The page supports both dark and light color schemes,
  and the page author prefers dark.
*/
:root {
  color-scheme: dark light;
}

Il meta tag color-scheme

Per rispettare la proprietà CSS color-scheme, è necessario scaricare prima il CSS (se vi viene fatto riferimento tramite <link rel="stylesheet">) e analizzarlo. Per aiutare gli user agent a visualizzare immediatamente lo sfondo della pagina con la combinazione di colori desiderata, puoi fornire un valore color-scheme anche in un elemento <meta name="color-scheme">.

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

Combinazione di color-scheme e prefers-color-scheme

Poiché sia il meta tag che la proprietà CSS (se applicata all'elemento :root) alla fine hanno lo stesso comportamento, consiglio sempre di specificare la combinazione di colori tramite il meta tag, in modo che il browser possa adottare più rapidamente lo schema preferito.

Sebbene per le pagine di riferimento assolute non siano necessarie ulteriori regole CSS, in generale dovresti sempre combinare color-scheme e prefers-color-scheme. Ad esempio, il colore CSS proprietario di WebKit -webkit-link, utilizzato da WebKit e Chrome per il link classico blu rgb(0,0,238), ha un rapporto di contrasto insufficiente di 2,23:1 su sfondo nero e non soddisfa sia i requisiti delle WCAG AA sia quelli delle WCAG AAA.

Ho aperto i bug per Chrome, WebKit e Firefox, nonché un meta problema nello standard HTML per risolvere il problema.

Interazione con prefers-color-scheme

L'interazione della proprietà CSS color-scheme e del meta tag corrispondente con la funzionalità multimediale delle preferenze utente di prefers-color-scheme può inizialmente sembrare confusa. Anzi, giocano molto bene insieme. La cosa più importante da capire è che color-scheme determina esclusivamente l'aspetto predefinito, mentre prefers-color-scheme determina l'aspetto stilizzato. Per maggiore chiarezza, supponiamo che la seguente pagina:

<head>
  <meta name="color-scheme" content="dark light">
  <style>
    fieldset {
      background-color: gainsboro;
    }
    @media (prefers-color-scheme: dark) {
      fieldset {
        background-color: darkslategray;
      }
    }
  </style>
</head>
<body>
  <p>
    Lorem ipsum dolor sit amet, legere ancillae ne vis.
  </p>
  <form>
    <fieldset>
      <legend>Lorem ipsum</legend>
      <button type="button">Lorem ipsum</button>
    </fieldset>
  </form>
</body>

Il codice CSS incorporato nella pagina imposta il valore background-color dell'elemento <fieldset> su gainsboro in genere e su darkslategray se l'utente preferisce una combinazione di colori dark in base alla funzionalità dei contenuti multimediali delle preferenze dell'utente prefers-color-scheme.

Tramite l'elemento <meta name="color-scheme" content="dark light">, la pagina comunica al browser che supporta un tema scuro e uno chiaro, con una preferenza per un tema scuro.

A seconda che il sistema operativo sia impostato sulla modalità Buio o Luce, l'intera pagina risulterà chiara su quella scura o viceversa, in base al foglio di stile dello user agent. Non è necessario alcun codice CSS aggiuntivo fornito dallo sviluppatore per modificare il testo del paragrafo o il colore di sfondo della pagina.

Nota come il valore background-color dell'elemento <fieldset> cambia a seconda che la modalità Buio sia attivata, seguendo le regole nel foglio di stile incorporato fornito dallo sviluppatore sulla pagina. È gainsboro o darkslategray.

Una pagina in modalità Luce.
Modalità Luce: stili specificati dallo sviluppatore e dallo user agent. Il testo è nero e lo sfondo è bianco, come indicato nel foglio di stile dello user agent. Il valore background-color dell'elemento <fieldset> è gainsboro secondo il foglio di stile incorporato per gli sviluppatori.
Una pagina in modalità Buio.
Modalità Buio: stili specificati dallo sviluppatore e dallo user agent. Il testo è bianco e lo sfondo è nero come indicato nel foglio di stile dello user agent. Il valore background-color dell'elemento <fieldset> è darkslategray secondo il foglio di stile incorporato per gli sviluppatori.

L'aspetto dell'elemento <button> è controllato dal foglio di stile dello user agent. Il valore color è impostato sul colore di sistema ButtonText, mentre background-color e i quattro border-color sono impostati sul colore di sistema ButtonFace.

Una pagina della modalità Luce che utilizza la proprietà ButtonFace.
Modalità Luce: background-color e i vari border-color sono impostati sul colore di sistema ButtonFace.

Ora nota come cambia il valore border-color dell'elemento <button>. Il valore calcolato per border-top-color e border-bottom-color passa da rgba(0, 0, 0, 0.847) (nero) a rgba(255, 255, 255, 0.847) (bianca), poiché lo user agent aggiorna ButtonFace in modo dinamico in base alla combinazione di colori. Lo stesso vale per l'elemento color dell'elemento <button> impostato sul colore di sistema corrispondente ButtonText.

Mostra che i valori di colore calcolati corrispondono a ButtonFace.
Modalità Luce: i valori calcolati di border-top-color e border-bottom-color che sono entrambi impostati su ButtonFace nel foglio di stile dello user agent sono ora rgba(0, 0, 0, 0.847).
Mostra che i valori del colore calcolati corrispondono ancora a ButtonFace in modalità Buio.
Modalità Buio: i valori calcolati di border-top-color e border-bottom-color entrambi impostati su ButtonFace nel foglio di stile dello user agent sono ora rgba(255, 255, 255, 0.847).

Demo

Puoi vedere gli effetti di color-scheme applicati a un numero elevato di elementi HTML in una demo su Glitch. La demo mostra deliberatamente la violazione delle WCAG AA e WCAG AAA con i colori dei link menzionati nell'avviso sopra riportato.

La demo in modalità Luce.
La demo è passata a color-scheme: light.
La demo in modalità Buio.
La demo è passata a color-scheme: dark. Prendi nota della violazione delle WCAG AA e delle WCAG AAA con i colori dei link.

Ringraziamenti

La proprietà CSS color-scheme e il meta tag corrispondente sono stati implementati da Rune Lillesveen. Rune è anche co-editor della specifica di livello 1 del modulo di aggiustamento del colore CSS. Immagine hero di Philippe Leone su Unsplash.