Verbessertes Standardstil im dunklen Modus mit der CSS-Eigenschaft „color-scheme“ und dem entsprechenden Meta-Tag

Mit der CSS-Eigenschaft color-scheme und dem entsprechenden Meta-Tag können Entwickler ihre Seiten für die themenspezifischen Standardeinstellungen des User-Agent-Stylesheets aktivieren.

Hintergrund

Die Media-Funktion „prefers-color-scheme“ für Nutzerpräferenzen

Mit der Media-Funktion für Nutzerpräferenzen prefers-color-scheme haben Entwickler die volle Kontrolle über das Erscheinungsbild ihrer Seiten. Wenn du dich damit noch nicht auskennst, lies bitte meinen Artikel prefers-color-scheme: Hello darkness, my old friend, in dem ich alles dokumentiert habe, was ich über die Entwicklung von großartigen Dark-Mode-Erlebnissen weiß.

Ein Puzzleteil, das im Artikel nur kurz erwähnt wurde, ist die CSS-Eigenschaft color-scheme und das entsprechende Meta-Tag mit demselben Namen. Beide erleichtern Ihnen als Entwickler die Arbeit, da Sie Ihre Seite für themenspezifische Standardeinstellungen des User-Agent-Stylesheets aktivieren können, z. B. für Formularsteuerelemente, Scrollbalken sowie CSS-Systemfarben. Gleichzeitig wird verhindert, dass Browser selbst Transformationen anwenden.

Unterstützte Browser

prefers-color-scheme

Browser Support

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 67.
  • Safari: 12.1.

Source

color-scheme

Browser Support

  • Chrome: 81.
  • Edge: 81.
  • Firefox: 96.
  • Safari: 13.

Source

User-Agent-Stylesheet

Bevor ich fortfahre, möchte ich kurz erklären, was ein User-Agent-Stylesheet ist. Meistens können Sie sich den User-Agent (UA) als eine elegante Bezeichnung für Browser vorstellen. Das UA-Stylesheet bestimmt das standardmäßige Erscheinungsbild einer Seite. Wie der Name schon sagt, ist ein UA-Stylesheet von dem jeweiligen UA abhängig. Sie können sich das UA-Stylesheet von Chrome (und Chromium) ansehen und es mit dem von Firefox oder von Safari (und WebKit) vergleichen. In der Regel stimmen UA-Stylesheets in den meisten Punkten überein. Beispielsweise werden Links in allen Browsern blau, allgemeiner Text schwarz und die Hintergrundfarbe weiß dargestellt. Es gibt aber auch wichtige (und manchmal störende) Unterschiede, z. B. bei der Formatierung von Formularsteuerelementen.

Sehen Sie sich das UA-Stylesheet von WebKit genauer an und erfahren Sie, was es im Zusammenhang mit dem Dark Mode bewirkt. Führen Sie eine Volltextsuche nach „dark“ im Stylesheet durch. Der vom Stylesheet bereitgestellte Standardwert ändert sich je nachdem, ob der Dark Mode aktiviert ist oder nicht. Zur Veranschaulichung sehen Sie hier eine solche CSS-Regel mit der Pseudoklasse :matches und WebKit-internen Variablen wie -apple-system-control-background sowie der WebKit-internen Präprozessordirektive #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 */
}

Sie werden feststellen, dass die Werte für die Attribute color und background-color oben nicht dem Standard entsprechen. Weder text noch -apple-system-control-background sind gültige CSS-Farben. Es handelt sich um WebKit-interne semantische Farben.

CSS hat standardisierte semantische Systemfarben. Sie werden in CSS Color Module Level 4 angegeben. Beispiel: Canvas (nicht zu verwechseln mit dem Tag <canvas>) wird für den Hintergrund von Anwendungsinhalten oder Dokumenten verwendet, während CanvasText für Text in Anwendungsinhalten oder Dokumenten verwendet wird. Die beiden gehören zusammen und sollten nicht isoliert verwendet werden.

In UA-Stylesheets können entweder eigene oder die standardisierten semantischen Systemfarben verwendet werden, um festzulegen, wie HTML-Elemente standardmäßig gerendert werden sollen. Wenn das Betriebssystem auf den dunklen Modus eingestellt ist oder ein dunkles Design verwendet, wird CanvasText (oder text) bedingt auf Weiß und Canvas (oder -apple-system-control-background) auf Schwarz gesetzt. Das UA-Stylesheet weist das folgende CSS dann nur einmal zu und deckt sowohl den hellen als auch den dunklen Modus ab.

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

Die CSS-Eigenschaft color-scheme

Die Spezifikation CSS Color Adjustment Module Level 1 führt ein Modell und Steuerelemente für die automatische Farbanpassung durch den User-Agent ein, um Nutzerpräferenzen wie den dunklen Modus, die Kontrastanpassung oder bestimmte gewünschte Farbschemas zu berücksichtigen.

Mit der darin definierten Property color-scheme kann ein Element angeben, mit welchen Farbschemas es gerendert werden soll. Diese Werte werden mit den Einstellungen des Nutzers abgeglichen. Das Ergebnis ist ein ausgewähltes Farbschema, das sich auf Elemente der Benutzeroberfläche auswirkt, z. B. auf die Standardfarben von Formularsteuerelementen und Scrollleisten sowie auf die verwendeten Werte der CSS-Systemfarben. Die folgenden Werte werden derzeit unterstützt:

  • normal: Das Element berücksichtigt keine Farbschemas und sollte daher mit dem Standardfarbschema des Browsers gerendert werden.

  • [ light | dark ]+: Gibt an, dass das Element die aufgeführten Farbschemas kennt und verarbeiten kann. Außerdem wird eine geordnete Präferenz zwischen den Farbschemas angegeben.

In dieser Liste steht light für ein helles Farbschema mit hellen Hintergrundfarben und dunklen Vordergrundfarben, während dark das Gegenteil darstellt, mit dunklen Hintergrundfarben und hellen Vordergrundfarben.

Bei allen Elementen sollte die Darstellung mit einem Farbschema dazu führen, dass die in der gesamten vom Browser bereitgestellten Benutzeroberfläche für das Element verwendeten Farben dem Zweck des Farbschemas entsprechen. Beispiele sind Scrollbalken, Rechtschreibprüfungsunterstreichungen und Formularsteuerelemente.

Beim Rendern des :root-Elements mit einem Farbschema muss sich dies zusätzlich auf die Oberflächenfarbe des Canvas (also die globale Hintergrundfarbe), den Anfangswert der color-Eigenschaft und die verwendeten Werte der Systemfarben auswirken. Außerdem sollten auch die Scrollleisten des Viewports betroffen sein.

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

Das Meta-Tag color-scheme

Damit die CSS-Property color-scheme berücksichtigt werden kann, muss das CSS zuerst heruntergeladen (wenn es über <link rel="stylesheet"> referenziert wird) und geparst werden. Damit User-Agents den Seitenhintergrund sofort mit dem gewünschten Farbschema rendern können, kann auch ein color-scheme-Wert in einem <meta name="color-scheme">-Element angegeben werden.

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

color-scheme und prefers-color-scheme kombinieren

Da sowohl das Meta-Tag als auch die CSS-Eigenschaft (wenn sie auf das :root-Element angewendet wird) letztendlich zum selben Verhalten führen, empfehle ich immer, das Farbschema über das Meta-Tag anzugeben, damit der Browser das bevorzugte Schema schneller übernehmen kann.

Für Seiten mit absoluter Baseline sind keine zusätzlichen CSS-Regeln erforderlich. Im Allgemeinen sollten Sie color-scheme jedoch immer mit prefers-color-scheme kombinieren. Die proprietäre WebKit-CSS-Farbe -webkit-link, die von WebKit und Chrome für das klassische Link-Blau rgb(0,0,238) verwendet wird, hat beispielsweise ein unzureichendes Kontrastverhältnis von 2,23:1 auf einem schwarzen Hintergrund und erfüllt weder die WCAG AA- noch die WCAG AAA-Anforderungen.

Ich habe Fehler für Chrome, WebKit und Firefox sowie ein Meta-Problem im HTML-Standard gemeldet, um das Problem zu beheben.

Interaktion mit prefers-color-scheme

Das Zusammenspiel der CSS-Eigenschaft color-scheme und des entsprechenden Meta-Tags mit der Media-Funktion prefers-color-scheme für Nutzereinstellungen kann anfangs verwirrend sein. Tatsächlich ergänzen sie sich sehr gut. Am wichtigsten ist es, zu verstehen, dass color-scheme ausschließlich das Standard-Erscheinungsbild bestimmt, während prefers-color-scheme das Erscheinungsbild bestimmt, das gestylt werden kann. Zur Veranschaulichung nehmen wir die folgende Seite an:

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

Der Inline-CSS-Code auf der Seite legt die background-color des <fieldset>-Elements im Allgemeinen auf gainsboro und auf darkslategray fest, wenn der Nutzer gemäß der Media-Funktion prefers-color-scheme eine dark-Farbschema bevorzugt.

Über das <meta name="color-scheme" content="dark light">-Element wird dem Browser mitgeteilt, dass die Seite ein dunkles und ein helles Design unterstützt, wobei ein dunkles Design bevorzugt wird.

Je nachdem, ob das Betriebssystem auf den dunklen oder hellen Modus eingestellt ist, wird die gesamte Seite im User-Agent-Stylesheet hell auf dunkel oder umgekehrt dargestellt. Es ist kein zusätzliches vom Entwickler bereitgestelltes CSS erforderlich, um den Absatztext oder die Hintergrundfarbe der Seite zu ändern.

Beachten Sie, wie sich die background-color des <fieldset>-Elements ändert, je nachdem, ob der Dark Mode aktiviert ist. Dabei werden die Regeln im vom Entwickler bereitgestellten Inline-Stylesheet auf der Seite berücksichtigt. Sie ist entweder gainsboro oder darkslategray.

Eine Seite im hellen Modus.
Heller Modus:Vom Entwickler und User-Agent angegebene Stile. Der Text ist schwarz und der Hintergrund ist weiß, wie im User-Agent-Stylesheet festgelegt. Die background-color des <fieldset>-Elements ist gemäß dem Inline-Entwickler-Stylesheet gainsboro.
Eine Seite im dunklen Modus.
Dunkler Modus:Vom Entwickler und vom User-Agent angegebene Stile. Der Text ist weiß und der Hintergrund ist schwarz, wie im User-Agent-Stylesheet festgelegt. Die background-color des <fieldset>-Elements ist gemäß dem Inline-Entwickler-Stylesheet darkslategray.

Das Erscheinungsbild des <button>-Elements wird durch das User-Agent-Stylesheet gesteuert. Der color-Wert ist auf die Systemfarbe ButtonText und der background-color-Wert sowie die vier border-color-Werte auf die Systemfarbe ButtonFace festgelegt.

Eine Seite im hellen Modus, auf der die ButtonFace-Eigenschaft verwendet wird.
Heller Modus:Das background-color und die verschiedenen border-colors sind auf die Systemfarbe ButtonFace festgelegt.

Beachten Sie nun, wie sich das border-color-Attribut des <button>-Elements ändert. Der berechnete Wert für border-top-color und border-bottom-color wechselt von rgba(0, 0, 0, 0.847) (schwarz) zu rgba(255, 255, 255, 0.847) (weiß), da der User-Agent ButtonFace dynamisch auf Grundlage des Farbschemas aktualisiert. Dasselbe gilt für das color-Attribut des <button>-Elements, das auf die entsprechende Systemfarbe ButtonText festgelegt ist.

Die berechneten Farbwerte stimmen mit „ButtonFace“ überein.
Heller Modus:Die berechneten Werte von border-top-color und border-bottom-color, die beide im User-Agent-Stylesheet auf ButtonFace festgelegt sind, sind jetzt rgba(0, 0, 0, 0.847).
Die berechneten Farbwerte stimmen auch im dunklen Modus mit „ButtonFace“ überein.
Dunkler Modus:Die berechneten Werte von border-top-color und border-bottom-color, die beide im User-Agent-Stylesheet auf ButtonFace festgelegt sind, sind jetzt rgba(255, 255, 255, 0.847).

Demo

Die Auswirkungen von color-scheme auf eine große Anzahl von HTML-Elementen können Sie sich in einer Demo auf Glitch ansehen. In der Demo wird absichtlich der Verstoß gegen WCAG AA und WCAG AAA mit den oben in der Warnung genannten Linkfarben gezeigt.

Die Demo im hellen Modus.
Die Demo wurde auf color-scheme: light gesetzt.
Die Demo im dunklen Modus.
Die Demo> wurde auf color-scheme: dark umgestellt. Beachten Sie den Verstoß gegen WCAG AA und WCAG AAA bei den Linkfarben.

Danksagungen

Die CSS-Property color-scheme und das entsprechende Meta-Tag wurden von Rune Lillesveen implementiert. Rune ist auch Mitautor der Spezifikation für das CSS Color Adjustment Module Level 1. Hero-Image von Philippe Leone auf Unsplash.