Amélioration du style par défaut du mode sombre avec la propriété CSS color-scheme et la balise Meta correspondante

La propriété CSS color-scheme et la balise Meta correspondante permettent aux développeurs d'activer les valeurs par défaut spécifiques au thème de la feuille de style du user-agent pour leurs pages.

Contexte

Fonctionnalité multimédia des préférences de l'utilisateur prefers-color-scheme

La fonctionnalité multimédia de préférences utilisateur prefers-color-scheme offre aux développeurs un contrôle total sur l'apparence de leurs pages. Si ce n'est pas votre cas, veuillez lire mon article prefers-color-scheme: Hello Darkness, my old friends, dans lequel j'ai recensé tout ce que je sais sur la création d'expériences exceptionnelles en mode sombre.

La propriété CSS color-scheme et la balise Meta correspondante du même nom n'ont fait que brièvement mention de l'article. Dans les deux cas, elles facilitent le travail de développeur en vous permettant d'activer les valeurs par défaut spécifiques à un thème de la feuille de style du user-agent sur votre page, telles que les commandes de formulaire, les barres de défilement et les couleurs système CSS. Dans le même temps, cette fonctionnalité empêche les navigateurs d'appliquer eux-mêmes des transformations.

Prise en charge des navigateurs

prefers-color-scheme

Navigateurs pris en charge

  • 76
  • 79
  • 67
  • 12.1

Source

color-scheme

Navigateurs pris en charge

  • 81
  • 81
  • 96
  • 13

Source

La feuille de style user-agent

Avant de poursuivre, permettez-moi de décrire brièvement ce qu'est une feuille de style user-agent. La plupart du temps, vous pouvez considérer le terme user-agent (UA) comme une façon sophistiquée d'utiliser le terme navigateur. La feuille de style UA détermine l'aspect par défaut d'une page. Comme son nom l'indique, une feuille de style UA est quelque chose qui dépend de l'UA en question. Vous pouvez consulter la feuille de style UA de Chrome (et de Chromium) et la comparer à celle de Firefox ou de Safari (et de WebKit). En règle générale, les feuilles de style UA s'accordent sur la plupart des points. Par exemple, les liens deviennent bleus, le texte général en noir et la couleur d'arrière-plan en blanc, mais il existe également des différences importantes (et parfois agaçantes), telles que le style des commandes de formulaire.

Examinez de plus près la feuille de style UA de WebKit et son rôle concernant le mode sombre. (Effectuez une recherche en texte intégral sur "dark" dans la feuille de style). La valeur par défaut fournie par la feuille de style change selon que le mode sombre est activé ou désactivé. Pour illustrer cela, voici une règle CSS utilisant la pseudo-classe :matches et les variables internes de WebKit telles que -apple-system-control-background, ainsi que la directive de préprocesseur WebKit interne #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 */
}

Vous remarquerez certaines valeurs non standards pour les propriétés color et background-color ci-dessus. Ni text, ni -apple-system-control-background ne sont des couleurs CSS valides. Il s'agit de couleurs sémantiques internes de WebKit.

Il s'avère que le CSS utilise des couleurs système sémantiques standardisées. Elles sont spécifiées dans le CSS Color Module Level 4. Par exemple, Canvas (à ne pas confondre avec la balise <canvas>) s'applique à l'arrière-plan du contenu ou des documents de l'application, tandis que CanvasText s'applique au texte contenu dans le contenu ou aux documents de l'application. Les deux sont liés et ne doivent pas être utilisés de façon isolée.

Les feuilles de style UA peuvent utiliser leurs propres couleurs propriétaires ou les couleurs du système sémantique standardisée pour déterminer le rendu des éléments HTML par défaut. Si le système d'exploitation est défini en mode sombre ou utilise un thème sombre, CanvasText (ou text) sera défini sur le blanc de manière conditionnelle, et Canvas (ou -apple-system-control-background) sera défini sur le noir. Ensuite, la feuille de style UA n'affecte le code CSS suivant qu'une seule fois, et couvre à la fois les modes clair et sombre.

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

Propriété CSS color-scheme

La spécification du module d'ajustement des couleurs CSS niveau 1 introduit un modèle et des commandes pour l'ajustement automatique des couleurs par le user-agent dans le but de gérer les préférences utilisateur, telles que le mode sombre, l'ajustement du contraste ou les jeux de couleurs spécifiques souhaités.

La propriété color-scheme définie ici permet à un élément d'indiquer les jeux de couleurs avec lesquels il peut être affiché à l'aise. Ces valeurs sont négociées selon les préférences de l'utilisateur, ce qui permet de choisir un jeu de couleurs qui affecte des éléments de l'interface utilisateur (UI), tels que les couleurs par défaut des commandes de formulaire et des barres de défilement, ainsi que les valeurs utilisées des couleurs système CSS. Les valeurs suivantes sont actuellement prises en charge :

  • normal indique que l'élément ne reconnaît pas du tout les jeux de couleurs et qu'il doit donc être affiché avec le jeu de couleurs par défaut du navigateur.

  • [ light | dark ]+ indique que l'élément connaît les jeux de couleurs listés et peut les gérer, et exprime une préférence ordonnée entre eux.

Dans cette liste, light représente un jeu de couleurs claires, avec des couleurs d'arrière-plan claires et des couleurs de premier plan sombres, tandis que dark représente le contraire, avec des couleurs d'arrière-plan sombres et des couleurs de premier plan claires.

Pour tous les éléments, le rendu avec un jeu de couleurs doit faire correspondre les couleurs utilisées dans toutes les interfaces utilisateur fournies par le navigateur pour l'élément avec l'intention du jeu de couleurs. Exemples : barres de défilement, traits de soulignement par le correcteur orthographique, commandes de formulaire, etc.

Dans l'élément :root, le rendu avec un jeu de couleurs doit également affecter la couleur de la surface du canevas (c'est-à-dire la couleur d'arrière-plan globale), la valeur initiale de la propriété color et les valeurs utilisées des couleurs système. Il doit également affecter les barres de défilement de la fenêtre d'affichage.

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

La balise Meta color-scheme

Pour respecter la propriété CSS color-scheme, le CSS doit d'abord être téléchargé (s'il est référencé via <link rel="stylesheet">) et analysé. Pour aider les user-agents à afficher immédiatement l'arrière-plan de la page avec le jeu de couleurs souhaité, une valeur color-scheme peut également être fournie dans un élément <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">

Combiner color-scheme et prefers-color-scheme

Étant donné que la balise Meta et la propriété CSS (si elle est appliquée à l'élément :root) entraînent à terme le même comportement, je recommande toujours de spécifier le jeu de couleurs via la balise Meta, afin que le navigateur puisse adopter le schéma préféré plus rapidement.

Bien qu'aucune règle CSS supplémentaire ne soit nécessaire pour les pages de référence absolues, en général, vous devez toujours combiner color-scheme avec prefers-color-scheme. Par exemple, la couleur CSS propriétaire de WebKit -webkit-link, utilisée par WebKit et Chrome pour le lien classique rgb(0,0,238) bleu, présente un rapport de contraste insuffisant de 2,23:1 sur un fond noir et ne respecte ni les normes WCAG AA, ni les exigences AAA des WCAG.

J'ai créé des bugs pour Chrome, WebKit et Firefox, ainsi qu'un problème de méta dans la norme HTML pour résoudre ce problème.

Interagir avec prefers-color-scheme

L'interaction entre la propriété CSS color-scheme et la balise Meta correspondante avec la fonctionnalité multimédia des préférences de l'utilisateur prefers-color-scheme peut sembler déroutante au premier abord. En fait, ils fonctionnent très bien ensemble. Il est essentiel de comprendre que color-scheme détermine exclusivement l'apparence par défaut, tandis que prefers-color-scheme détermine l'apparence stylable. Pour clarifier cela, supposons que la page suivante:

<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>

Le code CSS intégré à la page définit le background-color de l'élément <fieldset> sur gainsboro en général, et sur darkslategray si l'utilisateur préfère un jeu de couleurs dark selon la fonctionnalité multimédia des préférences de l'utilisateur prefers-color-scheme.

Via l'élément <meta name="color-scheme" content="dark light">, la page indique au navigateur qu'elle accepte les thèmes sombre et clair, avec une préférence pour un thème sombre.

Selon que le système d'exploitation est défini sur le mode sombre ou le mode clair, la page entière apparaît clairement ou en mode sombre, ou inversement, en fonction de la feuille de style du user-agent. Aucun CSS supplémentaire fourni par le développeur n'est nécessaire pour modifier le texte du paragraphe ou la couleur d'arrière-plan de la page.

Notez que le background-color de l'élément <fieldset> change selon que le mode sombre est activé ou non, en suivant les règles de la feuille de style intégrée fournie par le développeur sur la page. La valeur est gainsboro ou darkslategray.

Une page en mode clair.
Mode clair:styles spécifiés par le développeur et le user-agent. Le texte est noir et l'arrière-plan est blanc, conformément à la feuille de style du user-agent. Le background-color de l'élément <fieldset> est gainsboro selon la feuille de style de développement intégrée.
Une page en mode sombre.
Mode sombre:styles spécifiés par le développeur et le user-agent. Le texte est blanc et l'arrière-plan est noir, conformément à la feuille de style du user-agent. Le background-color de l'élément <fieldset> est darkslategray selon la feuille de style de développement intégrée.

L'apparence de l'élément <button> est contrôlée par la feuille de style du user-agent. Sa color est définie sur la couleur système ButtonText, et son background-color et les quatre border-color sont définis sur la couleur système ButtonFace.

Page en mode clair utilisant la propriété ButtonFace.
Mode clair:background-color et les différents border-color sont définis sur la couleur système ButtonFace.

Notez maintenant comment la valeur border-color de l'élément <button> change. La valeur calculée pour border-top-color et border-bottom-color passe de rgba(0, 0, 0, 0.847) (noir ou blanc) à rgba(255, 255, 255, 0.847) (blanc), car le user-agent met à jour ButtonFace de manière dynamique en fonction du jeu de couleurs. Il en va de même pour le color de l'élément <button> défini sur la couleur système correspondante ButtonText.

Montrer que les valeurs de couleur calculées correspondent à ButtonFace.
Mode clair:les valeurs calculées pour border-top-color et border-bottom-color, qui sont toutes deux définies sur ButtonFace dans la feuille de style du user-agent, sont désormais rgba(0, 0, 0, 0.847).
Montrer que les valeurs de couleur calculées correspondent toujours à ButtonFace en mode sombre.
Mode sombre:les valeurs calculées des border-top-color et border-bottom-color qui sont toutes deux définies sur ButtonFace dans la feuille de style user-agent sont désormais rgba(255, 255, 255, 0.847).

Démonstration

Vous pouvez voir les effets de color-scheme appliqués à un grand nombre d'éléments HTML dans une démonstration sur Glitch. La démonstration montre délibérément les non-respect des WCAG AA et WCAG AAA avec les couleurs des liens mentionnées dans l'avertissement ci-dessus.

La démo en mode clair.
La démonstration est passée à color-scheme: light.
La démo en mode sombre.
La démonstration est passée à color-scheme: dark. Notez les non-respects WCAG AA et WCAG AAA concernant les couleurs des liens.

Remerciements

La propriété CSS color-scheme et la balise Meta correspondante ont été implémentées par Rune Lillesveen. Rune est également co-éditeur de la spécification du module d'ajustement des couleurs CSS niveau 1. Image héros de Philippe Leone sur Unsplash.