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

Contesto

La funzionalità dei contenuti multimediali con preferenze dell'utente prefers-color-scheme

La funzionalità dei contenuti multimediali con le preferenze dell'utente prefers-color-scheme offre agli sviluppatori il controllo completo sull'aspetto delle loro pagine. Se non la conosci, leggi il mio articolo prefers-color-scheme: Ciao oscurità, mio vecchio amico, in cui ho documentato tutto ciò che so sulla creazione di fantastiche esperienze con la modalità Buio.

Un pezzo di puzzle menzionato solo brevemente nell'articolo è la proprietà CSS color-scheme e il corrispondente meta tag con lo stesso nome. Entrambi semplificano la vita di sviluppatore consentendoti di attivare nella tua pagina i valori predefiniti specifici del tema del foglio di stile dello user agent, 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

Fonte

color-scheme

Supporto dei browser

  • 81
  • 81
  • 96
  • 13

Fonte

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, la parola user agent (UA) è un modo sofisticato di dire browser. Il foglio di stile UA determina l'aspetto e il design predefiniti di una pagina. Come suggerisce il nome, un foglio di stile UA dipende dall'UA in questione. Puoi dare un'occhiata al foglio di stile UA di Chrome (e a Chromium) e confrontarlo con quello di Firefox o Safari (e WebKit). In genere, i fogli di stile UA concordano sulla maggior parte delle cose. Ad esempio, tutti gli elementi rendono i link blu, il testo generico nero e il colore di sfondo bianco, ma presentano anche differenze importanti (e a volte fastidiose), come lo stile dei controlli dei moduli.

Esamina più da vicino il foglio di stile UA di WebKit e cosa fa in merito alla modalità Buio. Esegui una ricerca del testo completo per "scuro" nel foglio di stile. Il valore predefinito fornito dal foglio di stile cambia a seconda che la modalità Buio sia attivata o disattivata. Per illustrare questo comportamento, ecco una regola CSS che utilizza la pseudoclasse :matches e le variabili interne di WebKit come -apple-system-control-background, nonché l'istruzione del preprocessore 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 indicate sopra. Né text-apple-system-control-background sono colori CSS validi. Sono colori semantici interni di WebKit.

Abbiamo scoperto che i colori del sistema CSS sono standardizzati. Sono specificati in Livello 4 del modulo colore CSS. 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. Questi due metodi sono collegati tra loro e non devono essere utilizzati separatamente.

I fogli di stile UA possono utilizzare colori proprietari o standardizzati del sistema semantico per determinare la modalità di rendering predefinita degli elementi HTML. Se il sistema operativo è impostato sulla modalità Buio o utilizza un tema scuro, CanvasText (o text) verrebbe impostato in modo condizionale sul bianco e Canvas (o -apple-system-control-background) verrebbe impostato sul nero. A questo punto, il foglio di stile UA assegna il seguente CSS solo una 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 per il livello 1 del modulo di regolazione del colore CSS 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 le specifiche combinazioni di colori desiderate.

La proprietà color-scheme definita nell'elemento consente a un elemento di indicare con quali combinazioni di colori è preferibile visualizzare. Questi valori vengono negoziati in base alle preferenze dell'utente, il che genera una scelta di combinazione di colori che influisce su elementi dell'interfaccia utente (UI), ad esempio 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 delle combinazioni di colori, pertanto deve essere visualizzato con la combinazione di colori predefinita del browser.

  • [ light | dark ]+ Indica che l'elemento conosce le combinazioni di colori elencate e può gestirle ed esprime una preferenza ordinata tra di loro.

In questo elenco, light rappresenta una combinazione di colori chiara, 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 sì che i colori utilizzati in tutte le UI fornite dal browser corrispondano allo scopo della combinazione di colori. Esempi: barre di scorrimento, sottolineature per il controllo ortografico, controlli modulo e così via.

Nell'elemento :root, il rendering con una combinazione di colori deve incidere 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. Inoltre, dovrebbe 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 onorare 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 lo sfondo della pagina con la combinazione di colori desiderata immediatamente, è possibile specificare anche un valore color-scheme 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) comportano lo stesso comportamento alla fine, consiglio sempre di specificare la combinazione di colori tramite il meta tag, in modo che il browser possa adottare più velocemente lo schema preferito.

Mentre per le pagine di riferimento assolute non sono necessarie regole CSS aggiuntive, in generale dovresti sempre combinare color-scheme con prefers-color-scheme. Ad esempio, il colore CSS proprietario -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 i requisiti WCAG AA e WCAG AAA.

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

Interazione con prefers-color-scheme

All'inizio l'interazione tra la proprietà CSS color-scheme e il meta tag corrispondente con la funzionalità dei contenuti multimediali delle preferenze dell'utente prefers-color-scheme può sembrare poco chiara. In effetti 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 stilibile. Per rendere il tutto più chiaro, supponiamo 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 generale e su darkslategray se l'utente preferisce una combinazione di colori dark in base alla funzionalità dei contenuti multimediali con preferenze dell'utente prefers-color-scheme.

Tramite l'elemento <meta name="color-scheme" content="dark light">, la pagina comunica al browser se 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 scuro o viceversa, in base al foglio di stile dello user agent. Non sono coinvolti altri CSS forniti 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 venga attivata o meno, seguendo le regole nel foglio di stile in linea fornito dallo sviluppatore sulla pagina. È gainsboro o darkslategray.

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

L'aspetto dell'elemento <button> è controllato dal foglio di stile dello user agent. Il suo color è impostato sul colore di sistema ButtonText mentre i suoi 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 l'elemento 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, perché lo user agent viene aggiornato 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 dei colori calcolati corrispondono a ButtonFace.
Modalità Luce: i valori calcolati di border-top-color e border-bottom-color impostati su ButtonFace nel foglio di stile dello user agent ora sono rgba(0, 0, 0, 0.847).
Mostra che i valori dei colori 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.

La demo in modalità Luce.
La demo è stata impostata su color-scheme: light.
La demo in modalità Buio.
La demo è stata impostata su color-scheme: dark. Annota la violazione delle 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 di livello 1 del modulo di regolazione del colore CSS. Immagine hero di Philippe Leone su Unsplash.