Sebbene sia più comunemente impostata sulla radice, la proprietà color-scheme può essere impostata su singoli elementi per forzarli in una combinazione di colori diversa rispetto al resto della pagina.
Questo può essere utile per i componenti che devono essere sempre visualizzati con una combinazione di colori specifica (ad es. sempre in modalità Buio o Luce).
Esempi di casi d'uso:
- Elementi che spesso sono in modalità Buio anche nelle pagine in modalità Luce per motivi estetici, ad esempio blocchi di codice, media player, gallerie fotografiche
- Le aree che contengono contenuti multimediali progettati per uno sfondo chiaro (ad es. immagini, video, illustrazioni, anteprime di stampa) possono essere impostate sulla modalità Luce anche se il resto della pagina è in modalità Buio.
- Elementi la cui combinazione di colori è controllata da un'impostazione a livello di utente, ad esempio le anteprime dei componenti
- Elementi incorporati che non supportano sia la modalità Luce che la modalità Buio
- Strumenti di progettazione, mappe, visualizzazioni, giochi e così via.
Quando cambiare i colori e quando forzare color-scheme?
Non tutti gli elementi che utilizzano testo più chiaro su sfondo più scuro in modalità Luce o testo più scuro su sfondo più chiaro in modalità Buio richiedono un color-scheme diverso.
Ad esempio, un pulsante principale potrebbe essere visualizzato in blu con testo bianco in modalità Luce, ma questo non giustifica un color-scheme: dark.
Come regola generale, gli elementi che utilizzano un color-scheme diverso sono in genere superfici complesse che stabiliscono il proprio contesto visivo, anziché semplici contenitori superficiali.
Quando valuti l'utilizzo di un color-scheme diverso su un elemento, chiediti:
- La UI del browser integrata che non è personalizzata in altro modo (ad es. controlli dei moduli, barre di scorrimento e così via) deve utilizzare questa combinazione di colori o adattarsi alla combinazione di colori della pagina? -> if the former, don't use
color-scheme. - I colori di
light-dark()devono essere risolti come per il resto della pagina o in base all'override? -> if the former, don't usecolor-scheme. - I discendenti devono essere in quel
color-scheme? In caso contrario, non utilizzarecolor-scheme.
Implementazione di base
Le sostituzioni specifiche dei componenti vengono in genere (anche se non necessariamente) utilizzate nelle pagine che supportano anche più combinazioni di colori tramite un color-scheme globale.
Per implementare correttamente la modalità Buio a livello di pagina, consulta Modalità Buio.
Una volta applicato un color-scheme a livello di pagina e se utilizzi token di colore sensibili (ad es. tramite light-dark()), puoi semplicemente impostare color-scheme su componenti specifici per eseguire l'override della modalità colore per quel sottoalbero:
pre, code, .dark {
color-scheme: dark;
}
Tieni presente che alcuni browser adattano comunque automaticamente i componenti a una combinazione di colori diversa.
Per forzare la combinazione di colori specificata in tutti i casi, utilizza only, ovvero color-scheme: only dark; anziché color-scheme: dark;.
Adattamento dei valori non relativi ai colori
Al momento, light-dark() funziona solo per i colori.
Best practice
- OBBLIGATORIO: non impostare
color-schemesu elementi senza sfondo, in quanto ciò rischia di mescolare coppie di colori di sfondo e di testo di combinazioni di colori diverse, con conseguente testo illeggibile. - FACOLTATIVO: anche se è più semplice riutilizzare le stesse coppie di colori della modalità Buio a livello di pagina, possiamo definire coppie di colori diverse per questi componenti. Ad esempio, potremmo voler rendere un componente della modalità Buio utilizzato in una pagina in modalità Luce un po' meno scuro rispetto a quando lo stesso componente della modalità Buio viene utilizzato in una pagina che è interamente in modalità Buio.
Problemi noti da tenere presenti
Aspetto importante: ereditarietà dei colori light-dark()
light-dark() viene risolto al momento del valore calcolato.
Ciò significa che tutte le proprietà <color> ereditate impostate su un colore light-dark() trasmetteranno ai relativi discendenti solo uno dei due colori, non l'espressione light-dark() stessa.
È incluso quanto segue:
- Proprietà dei colori integrate che vengono ereditate, come
color,accent-color,fill,stroke,text-shadow,caret-color - Qualsiasi proprietà personalizzata ereditabile registrata con
syntax: <color>einherits: true - Qualsiasi altra proprietà
<color>impostata suinherit
Ciò significa che dovresti:
- NON registrare proprietà personalizzate destinate a contenere token di progettazione (ad es.
--surface-color) come<color>. I token devono mantenere attiva l'espressionelight-dark()Express Live in modo che i discendenti possano risolverli nuovamente in uncolor-schemediverso. - Quando imposti
color-schemesu un elemento, specifica nuovamente tutte le proprietà<color>ereditate che potrebbero essere state impostate su valorilight-dark()(direttamente o tramite token di progettazione), anche se si tratta dello stesso token di progettazione. - NON utilizzare
inheritsulle proprietà<color>degli elementi con un overridecolor-scheme(puoi utilizzarlo sui relativi discendenti). - UTILIZZA le proprietà
<color>registrate per il caso d'uso opposto: quando vuoi deliberatamente acquisire un'istantanea del colore risolto dell'antenato e impedire che venga risolto nuovamente nelcolor-schemedel discendente. Ad esempio, l'acquisizione dello sfondo della pagina da utilizzare altrove. - Se devi animare un colore, utilizza una proprietà
<color>separata registrata con@propertysull'elemento animato (la registrazione è obbligatoria per l'interpolazione dei colori). Non si tratta di un token di progettazione, ma di un target di animazione per elemento, quindi non è in conflitto con la regola precedente.
Esempio:
:root {
--accent-color: light-dark(blue, skyblue);
--surface-color: light-dark(white, #222);
--text-color: light-dark(#111, white);
color-scheme: light dark;
accent-color: var(--accent-color);
color: var(--text-color);
}
body {
/* --surface-color dynamically switches despite being inherited because --surface-color is not registered */
background: var(--surface-color);
}
pre, code {
color-scheme: dark;
background: var(--surface-color);
/* Without this, accent-color would be blue, not skyblue! */
accent-color: var(--accent-color);
/* Without this, text-color would be #111, not white! */
color: var(--text-color);
}
Problemi da tenere presenti quando si utilizza color-scheme
- Chrome e Firefox rispettano
color-schemeper gli iframe: eseguono il rendering delle pagine incorporate nella combinazione di colori corretta e regolano la query supportiprefers-color-schemedella pagina incorporata in modo che riflettacolor-schemedel contesto di incorporamento. Safari non lo fa e risolveprefers-color-schemenell'impostazione di sistema anche all'interno degli iframe.- Se controlli sia l'elemento principale che l'iframe: passa esplicitamente la combinazione di colori dell'elemento principale all'iframe tramite un parametro URL (
?theme=dark) al momento della creazione dell'iframe o tramitepostMessage()(che ti consente anche di reagire alle modifiche di runtime). Nell'iframe, imposta una classe su<html>(e/ocolor-schemesu:root) da quell'indicatore anziché fare affidamento suprefers-color-scheme. - Se controlli solo la pagina incorporata: non esiste un modo affidabile per rilevare il
color-schemedel contesto di incorporamento dall'interno dell'iframe in Safari. Esponi un parametro del tema esplicito nell'API di incorporamento (ad esempio una stringa di query o un protocollopostMessage) e documentalo per gli incorporatori.
- Se controlli sia l'elemento principale che l'iframe: passa esplicitamente la combinazione di colori dell'elemento principale all'iframe tramite un parametro URL (
Strategie di riserva
Alternative e supporto del browser per color-scheme
La proprietà color-scheme è un potenziamento progressivo.
I browser che non la supportano ignoreranno questa proprietà e utilizzeranno la UI predefinita della modalità Luce.
Per adattarti alle preferenze dell'utente nei browser meno recenti, utilizza le query supporti prefers-color-scheme per fornire colori diversi quando è preferita la modalità Buio.
- Utilizza la query supporti per attivare le proprietà personalizzate su
:rootohtml - Evita di utilizzare la query supporti su singoli componenti, a meno che il componente non richieda un tipo molto specifico di personalizzazione della modalità Buio oltre ai colori.
:root {
/* Define brand colors for each mode */
--color-brand-light: #0056b3;
--color-brand-dark: #00e5ff;
--color-brand: var(--color-brand-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--color-brand: var(--color-brand-dark);
}
/* Ignored in older browsers */
color-scheme: light dark;
}
button.primary {
background-color: var(--color-brand);
}
Alternative e supporto del browser per light-dark()
Per i browser che supportano color-scheme, ma non ancora light-dark(), le versioni chiare e scure dei colori devono essere prima definite come proprietà personalizzate e la query supporti prefers-color-scheme deve essere utilizzata per impostare i colori per la rispettiva modalità, come nell'esempio seguente:
:root {
/* Define browser UI accent color for each mode */
--brand-accent-light: #0056b3;
--brand-accent-dark: #00e5ff;
--accent-color: var(--brand-accent-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--accent-color: var(--brand-accent-dark);
}
/* OPTIONAL: use light-dark() for more control of built-in UI colors */
@supports (color: light-dark(white, black)) {
--accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
}
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
/* Example inherited color property */
accent-color: var(--accent-color);
}
pre, code {
color-scheme: dark;
/* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
accent-color: var(--accent-color);
}