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 festlegen, dass ihre Seiten die thematisch spezifischen Standardeinstellungen des User-Agent-Stylesheets verwenden.

Hintergrund

Die Medienfunktion prefers-color-scheme für Nutzereinstellungen

Mit der Medienfunktion für Nutzereinstellungen von prefers-color-scheme haben Entwickler die volle Kontrolle über das Erscheinungsbild ihrer Seiten. Wenn Sie mit dem Thema nicht vertraut sind, lesen Sie bitte meinen Artikel prefers-color-scheme: Hallo Dunkelheit, mein alter Freund, in dem ich alles zusammengestellt habe, was ich über die Erstellung eines ansprechenden dunklen Modus weiß.

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

Unterstützte Browser

prefers-color-scheme

Unterstützte Browser

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

Quelle

color-scheme

Unterstützte Browser

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

Quelle

Das User-Agent-Stylesheet

Bevor ich fortfahre, möchte ich kurz erklären, was ein User-Agent-Stylesheet ist. Im Grunde ist der Begriff User-Agent (UA) eine ausgefallene Art, Browser zu sagen. Das UA-Stylesheet bestimmt das Standard-Erscheinungsbild einer Seite. Wie der Name schon sagt, hängt ein UA-Stylesheet von der jeweiligen UA ab. Sie können sich das UA-Stylesheet von Chrome (und Chromium) ansehen und mit dem von Firefox oder Safari (und WebKit) vergleichen. In der Regel stimmen UA-Stylesheets in den meisten Punkten überein. Beispielsweise ändern sie alle Links in Blau, den allgemeinen Text schwarz und die Hintergrundfarbe weiß. Es gibt aber auch wichtige (und manchmal ärgerliche) Unterschiede, z. B. beim Stil von Formularsteuerelementen.

Sehen Sie sich das UA-Stylesheet von WebKit genauer an und erfahren Sie, wie es sich auf den Dark Mode auswirkt. (Führen Sie im Stylesheet eine Volltextsuche nach „dark“ durch.) Der vom Stylesheet bereitgestellte Standard ändert sich je nachdem, ob der dunkle Modus aktiviert oder deaktiviert ist. Im Folgenden finden Sie ein Beispiel für eine solche CSS-Regel, die die Pseudoklasse :matches, WebKit-interne Variablen wie -apple-system-control-background und die WebKit-interne Preprocessor-Direktive #if defined verwendet:

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 sehen, dass für die Properties color und background-color oben einige nicht standardmäßige Werte angegeben sind. Weder text noch -apple-system-control-background sind gültige CSS-Farben. Es sind WebKit-interne semantische Farben.

Es stellt sich heraus, dass es in CSS standardisierte semantische Systemfarben gibt. Sie werden im CSS Color Module Level 4 (CSS-Farbmodul – Level 4) spezifiziert. Beispielsweise steht Canvas (nicht zu verwechseln mit dem Tag <canvas>) für den Hintergrund von Anwendungsinhalten oder Dokumenten, während CanvasText für Text in Anwendungsinhalten oder Dokumenten steht. Die beiden gehen Hand in Hand und sollten nicht getrennt voneinander verwendet werden.

Für 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 dann das folgende CSS 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-Property color-scheme

Die Spezifikation CSS Color Adjustment Module Level 1 (CSS-Modul zur Farbanpassung – Level 1) führt ein Modell und Steuerelemente für die automatische Farbanpassung durch den User-Agent ein. Ziel ist es, Nutzereinstellungen wie den dunklen Modus, die Kontrastanpassung oder bestimmte gewünschte Farbschemata zu berücksichtigen.

Mit der darin definierten Eigenschaft color-scheme kann ein Element angeben, mit welchem Farbschema es gerendert werden kann. Diese Werte werden mit den Präferenzen des Nutzers ausgehandelt. Daraus ergibt sich ein Farbschema, das sich auf Elemente der Benutzeroberfläche (UI) auswirkt, wie z. B. die Standardfarben von Formularsteuerelementen und Bildlaufleisten sowie die verwendeten Werte der CSS-Systemfarben. Die folgenden Werte werden derzeit unterstützt:

  • normal Gibt an, dass das Element keine Farbschemata kennt. Es sollte daher mit dem Standardfarbschema des Browsers gerendert werden.

  • [ light | dark ]+ Gibt an, dass das Element die aufgeführten Farbschemata kennt und verarbeiten kann, und gibt eine geordnete Präferenz zwischen ihnen an.

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

Bei allen Elementen sollte das Rendern mit einem Farbschema bewirken, dass die Farben, die in allen vom Browser bereitgestellten Benutzeroberflächen für das Element verwendet werden, mit der Absicht des Farbschemas übereinstimmen. Beispiele sind Scrollbalken, Unterstreichungen der Rechtschreibprüfung und Formularsteuerelemente.

Beim :root-Element muss das Rendern mit einem Farbschema außerdem die Oberflächenfarbe des Canvas (die globale Hintergrundfarbe), den Anfangswert der color-Eigenschaft und die verwendeten Werte der Systemfarben beeinflussen und sollte sich auch auf die Bildlaufleisten des Darstellungsbereichs auswirken.

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

Meta-Tag color-scheme

Damit die CSS-Property color-scheme berücksichtigt werden kann, muss das CSS zuerst heruntergeladen (falls 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 ein color-scheme-Wert auch 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.

Während für absolute Referenzseiten keine zusätzlichen CSS-Regeln erforderlich sind, sollten Sie color-scheme im Allgemeinen immer mit prefers-color-scheme kombinieren. Die proprietäre WebKit-CSS-Farbe -webkit-link, die von WebKit und Chrome für das klassische Blau der Links rgb(0,0,238) verwendet wird, hat beispielsweise ein unzureichendes Kontrastverhältnis von 2,23:1 auf einem schwarzen Hintergrund und verfehlt sowohl die Anforderungen der WCAG AA als auch der WCAG AAA.

Ich habe Programmfehler für Chrome, WebKit und Firefox sowie ein Meta-Problem im HTML-Standard geöffnet, um dieses Problem zu beheben.

Interaktion mit prefers-color-scheme

Das Zusammenspiel der color-scheme-CSS-Eigenschaft und des entsprechenden Meta-Tags mit der prefers-color-scheme-Medienfunktion für Nutzereinstellungen mag auf den ersten Blick verwirrend erscheinen. Sie ergänzen sich sogar sehr gut. Das Wichtigste ist, dass color-scheme ausschließlich das Standard-Aussehen bestimmt, während prefers-color-scheme das stilisierbare Aussehen bestimmt. Zur Verdeutlichung nehmen wir an, dass die folgende Seite geöffnet ist:

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

Durch den Inline-CSS-Code auf der Seite wird der background-color des <fieldset>-Elements im Allgemeinen auf gainsboro gesetzt. Außerdem wird er auf darkslategray gesetzt, wenn der Nutzer gemäß der Medienfunktion prefers-color-scheme der Nutzereinstellung ein dark-Farbschema bevorzugt.

Über das Element <meta name="color-scheme" content="dark light"> teilt die Seite dem Browser mit, dass sie 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 je nach User-Agent-Stylesheet hell auf dunkel oder umgekehrt angezeigt. Es ist kein zusätzliches vom Entwickler bereitgestelltes CSS erforderlich, um den Absatztext oder die Hintergrundfarbe der Seite zu ändern.

Wie sich der background-color des <fieldset>-Elements ändert, je nachdem, ob der dunkle Modus aktiviert ist oder nicht, richtet sich nach den Regeln im vom Entwickler bereitgestellten Inline-Stylesheet auf der Seite. Sie ist entweder gainsboro oder darkslategray.

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

Das Aussehen des <button>-Elements wird durch das User-Agent-Stylesheet gesteuert. Die color ist auf die Systemfarbe ButtonText und die background-color und die vier border-colors auf die Systemfarbe ButtonFace gesetzt.

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

Sehen Sie sich an, wie sich die border-color des <button>-Elements ändert. Der berechnete Wert für border-top-color und border-bottom-color ändert sich von rgba(0, 0, 0, 0.847) (schwarzstichig) zu rgba(255, 255, 255, 0.847) (weißstichig), da der User-Agent ButtonFace dynamisch basierend auf dem Farbschema aktualisiert. Dasselbe gilt für color des <button>-Elements, für das die entsprechende Systemfarbe ButtonText festgelegt ist.

Die berechneten Farbwerte stimmen mit „ButtonFace“ überein.
Heller Modus: Die berechneten Werte für 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 dem ButtonFace überein.
Dunkler Modus:Die berechneten Werte für border-top-color und border-bottom-color, die im User-Agent-Stylesheet auf ButtonFace festgelegt sind, sind jetzt rgba(255, 255, 255, 0.847).

Demo

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

Die Demo im hellen Modus
Die Demo wurde zu color-scheme: light umgeschaltet.
Die Demo im dunklen Modus.
Die Demo wurde zu color-scheme: dark umgeschaltet. Beachten Sie den Verstoß gegen die WCAG AA- und WCAG AAA-Anforderungen hinsichtlich der Linkfarben.

Danksagungen

Die CSS-Property color-scheme und das entsprechende Meta-Tag wurden von Rune Lillesveen implementiert. Rune ist auch Mitbearbeiter der CSS-Spezifikation für das Farbkorrekturmodul der Stufe 1. Hero-Image von Philippe Leone auf Unsplash