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'utiliser les valeurs par défaut spécifiques au thème de la feuille de style user-agent pour leurs pages.

Contexte

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

La fonctionnalité multimédia de préférences utilisateur prefers-color-scheme donne aux développeurs un contrôle total sur l'apparence de leurs pages. Si vous ne connaissez pas bien ce mode, veuillez lire mon article prefers-color-scheme: Hello darkness, my old friends, où j'ai documenté tout ce que je sais sur la création d'expériences incroyables en mode sombre.

La propriété CSS color-scheme et la balise Meta correspondante du même nom sont la pièce de puzzle que nous avons mentionnée brièvement dans l'article. Ils facilitent tous deux votre vie de développeur en vous permettant d'activer les valeurs par défaut spécifiques au thème de la feuille de style du user-agent pour votre page, comme les commandes de formulaire, les barres de défilement et les couleurs système CSS. En parallèle, 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

Feuille de style user-agent

Avant de continuer, permettez-moi de vous présenter brièvement ce qu'est une feuille de style user-agent. La plupart du temps, le terme user-agent (UA) est une expression sophistiquée d'navigateur. La feuille de style UA détermine l'apparence par défaut d'une page. Comme son nom l'indique, une feuille de style UA 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 sont d'accord sur la majorité des points. Par exemple, ils affichent tous des liens bleus, texte général en noir et couleur d'arrière-plan blanc, mais il existe également des différences importantes (et parfois agaçantes), comme la façon dont ils stylisent les commandes des formulaires.

Examinez de plus près la feuille de style UA de WebKit et son impact sur le mode sombre. (Recherchez "dark" dans la feuille de style en texte intégral.) 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 qui utilise la pseudo-classe :matches, des variables WebKit-internal telles que -apple-system-control-background, ainsi que la directive de préprocesseur WebKit-internal #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 WebKit.

Il s'avère que le CSS utilise des couleurs système sémantiques standardisées. Elles sont spécifiées dans le niveau 4 du module de couleur CSS. Par exemple, Canvas (à ne pas confondre avec la balise <canvas>) correspond à l'arrière-plan du contenu ou des documents de l'application, tandis que CanvasText correspond au texte dans le contenu ou les documents de l'application. Les deux sont complémentaires et ne doivent pas être utilisés séparément.

Les feuilles de style UA peuvent utiliser leurs propres couleurs propriétaires ou les couleurs du système sémantique standardisées pour déterminer comment les éléments HTML doivent être affichés par défaut. Si le système d'exploitation est défini sur le mode sombre ou utilise un thème sombre, CanvasText (ou text) sera défini sur blanc de manière conditionnelle, et Canvas (ou -apple-system-control-background) sera défini sur noir. Ensuite, la feuille de style UA attribue le CSS suivant une seule fois et couvre 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 niveau 1 du module d'ajustement des couleurs CSS introduit un modèle et des commandes pour l'ajustement automatique des couleurs par le user-agent. L'objectif est 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 qui y est définie permet à un élément d'indiquer les jeux de couleurs avec lesquels il peut être affiché. Ces valeurs sont négociées en fonction des préférences de l'utilisateur, ce qui donne lieu à un jeu de couleurs qui affecte les éléments de l'interface utilisateur, 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 connaît pas du tout les jeux de couleurs. 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 répertorié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 clair, avec des couleurs d'arrière-plan claires et des couleurs sombres au premier plan, tandis que dark représente le contraire, avec des couleurs d'arrière-plan sombres et des couleurs claires au premier plan.

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

Sur l'élément :root, le rendu avec un jeu de couleurs doit également affecter la couleur de 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;
}

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 le jeu de couleurs souhaité en arrière-plan de la page, 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 elles sont appliquées à l'élément :root) aboutissent au même comportement, je vous recommande de toujours 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 -webkit-link de WebKit, utilisée par WebKit et Chrome pour le rgb(0,0,238) classique bleu, présente un rapport de contraste insuffisant de 2,23:1 sur un fond noir et ne respecte pas les WCAG AA ni les exigences WCAG AAA.

J'ai ouvert des bugs pour Chrome, WebKit et Firefox, ainsi qu'un meta-problème dans la norme HTML pour résoudre ce problème.

Interagir avec prefers-color-scheme

L'interaction de la propriété CSS color-scheme et de la balise Meta correspondante avec la fonctionnalité multimédia prefers-color-scheme des préférences de l'utilisateur 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 stylisée. Pour clarifier cela, supposons que vous reteniez 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 prefers-color-scheme de préférences utilisateur.

Via l'élément <meta name="color-scheme" content="dark light">, la page indique au navigateur qu'il accepte les thèmes sombre et clair, en privilégiant un thème sombre.

Selon que le système d'exploitation est défini sur le mode sombre ou clair, l'ensemble de la page apparaît clair ou sombre, ou inversement, selon la feuille de style de l'user-agent. Il n'existe aucun CSS fourni par le développeur supplémentaire 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, conformément aux règles de la feuille de style intégrée fournie par le développeur sur la page. gainsboro ou darkslategray.

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

L'apparence de l'élément <button> est contrôlée par la feuille de style du user-agent. Son color est défini 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 du mode clair utilisant la propriété ButtonFace.
Mode clair:le background-color et les différents border-color sont définis sur la couleur système ButtonFace.

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

Les valeurs de couleur calculées correspondent à ButtonFace.
Mode clair:les valeurs calculées de border-top-color et de border-bottom-color qui sont toutes deux définies sur ButtonFace dans la feuille de style de l'user-agent sont désormais rgba(0, 0, 0, 0.847).
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 du 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 le non-respect des WCAG AA et des WCAG AAA avec les couleurs de lien mentionnées dans l'avertissement ci-dessus.

Démonstration en mode clair.
La démonstration est passée sur color-scheme: light.
Démonstration en mode sombre.
La démonstration est passée sur color-scheme: dark. Notez le non-respect des 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 CSS Color Adjust Module Level 1. Image principale de Philippe Leone sur Unsplash.