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 le impostazioni predefinite specifiche del tema del foglio di stile dello user agent per le loro pagine.

Sfondo

Funzionalità multimediale per le preferenze utente prefers-color-scheme

La funzionalità prefers-color-scheme media delle preferenze utente offre agli sviluppatori il pieno controllo dell'aspetto delle loro pagine. Se non la conosci, leggi il mio articolo prefers-color-scheme: Hello darkness, my old friend, in cui ho documentato tutto ciò che so sulla creazione di esperienze straordinarie in modalità Buio.

Un elemento del puzzle menzionato solo brevemente nell'articolo è la proprietà CSS color-scheme e il metatag corrispondente con lo stesso nome. Entrambi semplificano la vita degli sviluppatori consentendo di attivare i valori predefiniti specifici del tema del foglio di stile dello user agent, ad esempio controlli dei moduli, barre di scorrimento e colori di sistema CSS. Allo stesso tempo, questa funzionalità impedisce ai browser di applicare autonomamente qualsiasi trasformazione.

Supporto browser

prefers-color-scheme

Browser Support

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 67.
  • Safari: 12.1.

Source

color-scheme

Browser Support

  • Chrome: 81.
  • Edge: 81.
  • Firefox: 96.
  • Safari: 13.

Source

Il foglio di stile dello user agent

Prima di continuare, vorrei descrivere brevemente che cos'è un foglio di stile user agent. La maggior parte delle volte, puoi pensare alla parola user agent (UA) come a un modo elegante per dire browser. Il foglio di stile UA determina l'aspetto predefinito di una pagina. Come suggerisce il nome, un foglio di stile UA dipende dalla UA in questione. Puoi dare un'occhiata al foglio di stile UA di Chrome (e Chromium) e confrontarlo con quello di Firefox o Safari (e WebKit). In genere, i fogli di stile UA sono concordi sulla maggior parte delle cose. Ad esempio, tutti rendono i link blu, il testo generale nero e il colore di sfondo bianco, ma ci sono anche differenze importanti (e a volte fastidiose), ad esempio, il modo in cui vengono stilizzati i controlli dei moduli.

Dai un'occhiata più da vicino al foglio di stile UA di WebKit e a cosa fa per quanto riguarda la modalità Buio. Esegui una ricerca a testo intero di "dark" nel foglio di stile. Il valore predefinito fornito dal foglio di stile cambia a seconda che la modalità Buio sia attiva o disattivata. Per illustrare questo concetto, ecco una regola CSS che utilizza la pseudo classe :matches e variabili interne di WebKit come -apple-system-control-background, nonché la direttiva del preprocessor interno di 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. Si tratta di colori semantici interni a WebKit.

Il CSS ha standardizzato i colori semantici di sistema. Sono specificati nel CSS Color Module Level 4. Ad esempio, Canvas (da non confondere con il tag <canvas>) è per lo sfondo dei contenuti o dei documenti dell'applicazione, mentre CanvasText è per il testo nei contenuti o nei documenti dell'applicazione. I due valori vanno di pari passo e non devono essere utilizzati separatamente.

I fogli di stile UA possono utilizzare i propri colori proprietari o quelli del sistema semantico standardizzato, per determinare il rendering predefinito degli elementi HTML. Se il sistema operativo è impostato sulla modalità Buio o utilizza un tema scuro, CanvasText (o text) verrà impostato in modo condizionale sul bianco e Canvas (o -apple-system-control-background) verrà impostato sul nero. Il foglio di stile UA assegna quindi il seguente CSS una sola volta e copre sia la modalità Luce che 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 CSS Color Adjustment Module Level 1 introduce un modello e 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 schemi di colori specifici desiderati.

La proprietà color-scheme definita al suo interno consente a un elemento di indicare con quali combinazioni di colori può essere visualizzato. Questi valori vengono negoziati con le preferenze dell'utente, il che comporta la scelta di una combinazione di colori che influisce su elementi dell'interfaccia utente (UI) come i colori predefiniti dei controlli dei moduli e delle barre di scorrimento, nonché sui valori utilizzati dei colori di sistema CSS. Al momento sono supportati i seguenti valori:

  • normal Indica che l'elemento non è a conoscenza degli schemi di colori e quindi deve essere visualizzato con lo schema di colori predefinito del browser.

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

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

Per tutti gli elementi, il rendering con una combinazione di colori deve fare in modo che i colori utilizzati in tutta l'interfaccia utente fornita dal browser per l'elemento corrispondano all'intento della combinazione di colori. Esempi sono le barre di scorrimento, le sottolineature del controllo ortografico, i controlli dei moduli e così via.

Nell'elemento :root, il rendering con una combinazione di colori deve influire anche 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, e deve influire anche sulle barre di scorrimento del riquadro.

/*
  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 viene fatto riferimento tramite <link rel="stylesheet">) e analizzarlo. Per aiutare gli user agent a eseguire il rendering dello sfondo della pagina con la combinazione di colori desiderata immediatamente, un valore color-scheme può essere fornito 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 sia la proprietà CSS (se applicata all'elemento :root) alla fine producono lo stesso comportamento, consiglio sempre di specificare lo schema di colori tramite il meta tag, in modo che il browser possa adottare più rapidamente lo schema preferito.

Mentre per le pagine di base assolute non sono necessarie regole CSS aggiuntive, nel caso generale devi sempre combinare color-scheme con prefers-color-scheme. Ad esempio, il colore CSS proprietario di WebKit -webkit-link, utilizzato da WebKit e Chrome per il classico blu dei link rgb(0,0,238), ha un rapporto di contrasto insufficiente di 2,23:1 su uno sfondo nero e non soddisfa i requisiti WCAG AA e WCAG AAA.

Ho segnalato bug per Chrome, WebKit e Firefox e ho creato un problema meta nello standard HTML per risolvere il problema.

Interplay con prefers-color-scheme

L'interazione tra la proprietà CSS color-scheme e il tag meta corrispondente con la funzionalità dei contenuti multimediali delle preferenze utente prefers-color-scheme può sembrare confusa all'inizio. Infatti, 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 personalizzabile. Per rendere più chiaro il concetto, considera 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 background-color dell'elemento <fieldset> su gainsboro nel caso generale e su darkslategray se l'utente preferisce una combinazione di colori dark in base alla funzionalità dei contenuti multimediali delle preferenze 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 il tema scuro.

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

Nota come cambia background-color dell'elemento <fieldset> a seconda che la modalità buio sia attivata, seguendo le regole nel foglio di stile incorporato fornito dallo sviluppatore nella 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 da foglio di stile dell'user agent. Il background-color dell'elemento <fieldset> è gainsboro come da foglio di stile dello sviluppatore incorporato.
Una pagina in modalità Buio.
Modalità Buio: stili specificati dallo sviluppatore e dallo user agent. Il testo è bianco e lo sfondo è nero, come da foglio di stile dell'user agent. Il background-color dell'elemento <fieldset> è darkslategray come da foglio di stile dello sviluppatore incorporato.

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

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

Ora nota come cambia 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) (bianco), poiché lo user agent aggiorna ButtonFace in modo dinamico in base alla combinazione di colori. Lo stesso vale per l'elemento <button> color impostato sul colore di sistema corrispondente ButtonText.

Mostra che i valori di colore calcolati corrispondono a ButtonFace.
Modalità Chiaro:i valori calcolati di border-top-color e border-bottom-color, entrambi impostati su ButtonFace nel foglio di stile dell'user agent, ora sono rgba(0, 0, 0, 0.847).
Mostra che i valori di 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 dell'user agent, ora sono 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 precedente.

La demo in modalità Luce.
La demo è stata attivata su color-scheme: light.
La demo in modalità Buio.
La demo è stata attivata su color-scheme: dark. Nota la violazione WCAG AA e 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 del modulo di regolazione del colore CSS di livello 1. Immagine promozionale di Philippe Leone su Unsplash.