Bien qu'elle soit plus souvent définie sur la racine, la propriété color-scheme peut être définie sur des éléments individuels pour les forcer à utiliser un jeu de couleurs différent de celui du reste de la page.
Cela peut être utile pour les composants qui doivent toujours être affichés dans un jeu de couleurs spécifique (par exemple, toujours en mode sombre ou clair).
Voici quelques exemples de cas d'utilisation :
- Éléments qui sont souvent en mode sombre, même sur les pages en mode clair, pour des raisons esthétiques (par exemple, les blocs de code, les lecteurs multimédias, les galeries de photos)
- Les zones contenant des contenus multimédias conçus pour un arrière-plan clair (par exemple, des images, des vidéos, des illustrations ou des aperçus avant impression) peuvent être définies sur le mode clair, même si le reste de la page est en mode sombre.
- Éléments dont le jeu de couleurs est contrôlé par un paramètre au niveau de l'utilisateur, comme les aperçus de composants
- Intégrations non compatibles avec les modes clair et sombre
- Outils de conception, cartes, visualisations, jeux, etc.
Quand modifier les couleurs et quand forcer color-scheme ?
Tous les éléments qui utilisent du texte plus clair sur un arrière-plan plus sombre en mode clair ou du texte plus sombre sur un arrière-plan plus clair en mode sombre n'ont pas besoin d'un color-scheme différent.
Par exemple, un bouton principal peut s'afficher en bleu avec du texte blanc en mode clair, mais cela ne justifie pas un color-scheme: dark.
En règle générale, les éléments utilisant un color-scheme différent sont des surfaces complexes qui établissent leur propre contexte visuel, plutôt que de simples conteneurs peu profonds.
Lorsque vous envisagez d'utiliser un autre color-scheme sur un élément, posez-vous les questions suivantes :
- L'UI du navigateur intégrée qui n'est pas personnalisée (par exemple, les commandes de formulaire, les barres de défilement, etc.) doit-elle utiliser ce jeu de couleurs ou s'adapter à celui de la page ? -> Si c'est le cas, n'utilisez pas
color-scheme. - Les couleurs
light-dark()doivent-elles être résolues comme pour le reste de la page ou en fonction du remplacement ? -> Si c'est le cas, n'utilisez pascolor-scheme. - Les descendants doivent-ils se trouver dans ce
color-scheme? Si ce n'est pas le cas, n'utilisez pascolor-scheme.
Implémentation de base
Les remplacements spécifiques aux composants sont généralement (mais pas nécessairement) utilisés sur les pages qui acceptent également plusieurs jeux de couleurs via un color-scheme global.
Pour implémenter correctement le mode sombre sur l'ensemble de la page, consultez Mode sombre.
Une fois qu'un color-scheme à l'échelle de la page est en place et que vous utilisez des jetons de couleur sensibles à celui-ci (par exemple, via light-dark()), vous pouvez simplement définir color-scheme sur des composants spécifiques pour remplacer le mode de couleur de cette sous-arborescence :
pre, code, .dark {
color-scheme: dark;
}
Notez que certains navigateurs adaptent automatiquement les composants à un autre jeu de couleurs.
Pour forcer le jeu de couleurs spécifié dans tous les cas, utilisez only, c'est-à-dire color-scheme: only dark; au lieu de color-scheme: dark;.
Adapter les valeurs non chromatiques
light-dark() ne fonctionne actuellement que pour les couleurs.
Bonnes pratiques
- OBLIGATOIRE : Ne définissez pas
color-schemesur des éléments sans arrière-plan, car cela risque de mélanger des paires de couleurs d'arrière-plan et de texte de différents jeux de couleurs, ce qui rendrait le texte illisible. - FACULTATIF : Bien qu'il soit plus facile de réutiliser les mêmes paires de couleurs que pour le mode sombre à l'échelle de la page, nous pouvons définir des paires de couleurs différentes pour ces composants. Par exemple, nous pouvons souhaiter qu'un composant en mode sombre utilisé dans une page en mode clair soit un peu moins sombre que lorsque le même composant en mode sombre est utilisé dans une page qui est globalement en mode sombre.
Problèmes connus à prendre en compte
Piège important : héritage des couleurs light-dark()
light-dark() est résolu au moment de la valeur calculée.
Cela signifie que toutes les propriétés <color> héritées définies sur une couleur light-dark() ne transmettront qu'une des deux couleurs à leurs descendants, et non l'expression light-dark() elle-même.
Par exemple :
- Propriétés de couleur intégrées qui héritent, telles que
color,accent-color,fill,stroke,text-shadow,caret-color - Toutes les propriétés personnalisées héritables enregistrées avec
syntax: <color>etinherits: true - Toute autre propriété
<color>définie surinherit
Ce que cela implique pour vous :
- NE PAS enregistrer les propriétés personnalisées destinées à contenir des jetons de conception (par exemple,
--surface-color) en tant que<color>. Les jetons doivent conserver leur expressionlight-dark()active afin que les descendants puissent les résoudre à nouveau sous un autrecolor-scheme. - Lorsque vous définissez
color-schemesur un élément, spécifiez à nouveau toutes les propriétés<color>héritées qui ont pu être définies sur des valeurslight-dark()(directement ou via des jetons de conception), même s'il s'agit du même jeton de conception. - NE PAS utiliser
inheritsur les propriétés<color>des éléments avec un remplacementcolor-scheme(vous pouvez l'utiliser sur leurs descendants). - À FAIRE : Utilisez les propriétés
<color>enregistrées pour le cas d'utilisation inverse, c'est-à-dire lorsque vous souhaitez délibérément capturer la couleur résolue de l'ancêtre et l'empêcher d'être résolue à nouveau sous lecolor-schemedu descendant. Par exemple, capturer l'arrière-plan de la page pour l'utiliser ailleurs. - Si vous devez animer une couleur, utilisez une propriété
<color>distincte enregistrée par@propertysur l'élément animé (l'enregistrement est requis pour l'interpolation des couleurs). Il ne s'agit pas d'un jeton de conception, mais d'une cible d'animation par élément. Elle n'entre donc pas en conflit avec la règle ci-dessus.
Exemple :
: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);
}
Problèmes à prendre en compte lors de l'utilisation de color-scheme
- Chrome et Firefox respectent
color-schemepour les iFrames : ils affichent les pages intégrées dans le bon jeu de couleurs et ajustent la requête médiaprefers-color-schemede la page intégrée pour refléter lecolor-schemedu contexte d'intégration. Safari ne le fait pas et résoutprefers-color-schemeen fonction du paramètre système, même dans les iFrames.- Si vous contrôlez à la fois la page parent et l'iframe : transmettez explicitement le jeu de couleurs de la page parent à l'iframe, via un paramètre d'URL (
?theme=dark) au moment de la construction de l'iframe ou viapostMessage()(qui vous permet également de réagir aux modifications d'exécution). Dans l'iframe, définissez une classe sur<html>(et/oucolor-schemesur:root) à partir de ce signal au lieu de vous appuyer surprefers-color-scheme. - Si vous ne contrôlez que la page intégrée : il n'existe aucun moyen fiable de détecter le
color-schemedu contexte d'intégration depuis l'iFrame dans Safari. Exposez un paramètre de thème explicite sur votre API d'intégration (par exemple, une chaîne de requête ou un protocolepostMessage) et documentez-le pour les intégrateurs.
- Si vous contrôlez à la fois la page parent et l'iframe : transmettez explicitement le jeu de couleurs de la page parent à l'iframe, via un paramètre d'URL (
Stratégies de remplacement
Solutions de remplacement et compatibilité des navigateurs avec color-scheme
La propriété color-scheme est une amélioration progressive.
Les navigateurs qui ne sont pas compatibles ignoreront cette propriété et utiliseront leur UI par défaut en mode clair.
Pour s'adapter aux préférences de l'utilisateur dans les anciens navigateurs, utilisez les requêtes média prefers-color-scheme pour fournir différentes couleurs lorsque le mode sombre est préféré.
- Utilisez la requête média pour activer les propriétés personnalisées sur
:rootouhtml. - Évitez d'utiliser la requête média sur des composants individuels, sauf si le composant nécessite un type de personnalisation du mode sombre très spécifique au-delà des couleurs.
: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);
}
Solutions de remplacement et compatibilité des navigateurs pour light-dark()
Pour les navigateurs qui sont compatibles avec color-scheme, mais pas encore avec light-dark(), les versions claires et sombres des couleurs doivent d'abord être définies en tant que propriétés personnalisées. La requête média prefers-color-scheme doit être utilisée pour définir les couleurs du mode correspondant, comme dans l'exemple ci-dessous :
: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);
}