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 Funktionen erleichtern Ihnen als Entwickler die Arbeit, da Sie für Ihre Seite thematisch passende Standardeinstellungen des User-Agent-Stylesheets aktivieren können, z. B. für 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. So sind beispielsweise alle Links blau, allgemeiner Text schwarz und die Hintergrundfarbe weiß. Es gibt aber auch wichtige (und manchmal ärgerlich) Unterschiede, z. B. bei der Formatierung von Formularelementen.

Sehen Sie sich das UA-Stylesheet von WebKit genauer an und erfahren Sie, wie es sich auf den Dark Mode auswirkt. (Führen Sie eine Volltextsuche im Stylesheet nach „dunkel“ durch.) Der vom Stylesheet bereitgestellte Standard ändert sich je nachdem, ob der dunkle Modus aktiviert oder deaktiviert ist. Im Folgenden finden Sie eine solche CSS-Regel mit der Pseudoklasse :matches, WebKit-internen Variablen wie -apple-system-control-background und der WebKit-internen Preprocessor-Direktive #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 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 handelt sich um semantisches WebKit-internes Farbschema.

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 <canvas>-Tag) 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.

UA-Stylesheets können entweder eigene oder die standardisierten semantischen Systemfarben verwenden, 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 Property color-scheme kann ein Element angeben, mit welchen Farbschemata es gerendert werden kann. Diese Werte werden mit den Einstellungen des Nutzers verhandelt, was zu einem ausgewählten Farbschema führt, das sich auf Elemente der Benutzeroberfläche (UI) wie die Standardfarben von Formularelementen und Bildlaufleisten sowie die verwendeten Werte der CSS-Systemfarben auswirkt. 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.

Beim Rendern mit einem Farbschema sollten die Farben, die in der gesamten vom Browser bereitgestellten Benutzeroberfläche für das Element verwendet werden, mit dem beabsichtigten Farbschema übereinstimmen. Beispiele sind Scrollbalken, Unterstreichungen der Rechtschreibprüfung und Formularsteuerelemente.

Beim Element :root muss das Rendern mit einem Farbschema zusätzlich die Oberfläche des Canvas (d. h. die globale Hintergrundfarbe), den Anfangswert der Eigenschaft color und die verwendeten Werte der Systemfarben beeinflussen. Außerdem sollten die Bildlaufleisten des Viewports betroffen sein.

/*
  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.

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 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 Fehlerberichte für Chrome, WebKit und Firefox sowie ein Meta-Problem im HTML-Standard eingereicht, um dieses Problem zu beheben.

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

Der Inline-CSS-Code auf der Seite legt den Wert von background-color des <fieldset>-Elements im Allgemeinen auf gainsboro fest und auf darkslategray, wenn der Nutzer gemäß der Medienfunktion für Nutzereinstellungen prefers-color-scheme 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 wird kein zusätzliches vom Entwickler bereitgestelltes CSS verwendet, um den Text des Absatzes oder die Hintergrundfarbe der Seite zu ändern.

Beachten Sie, dass sich das background-color des Elements <fieldset> je nach Aktivierung des dunklen Modus ändert, gemäß 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 ist weiß, gemäß dem User-Agent-Stylesheet. Die background-color des <fieldset>-Elements ist gainsboro gemäß dem eingefügten 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. Die background-color des <fieldset>-Elements ist darkslategray gemäß dem eingefügten 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, auf der die Eigenschaft „ButtonFace“ verwendet wird.
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 das Attribut color des Elements <button>, das auf die entsprechende Systemfarbe ButtonText festgelegt ist.

Die berechneten Farbwerte stimmen mit „ButtonFace“ überein.
Hellmodus:Die berechneten Werte für border-top-color und border-bottom-color, die im User-Agent-Stylesheet auf ButtonFace festgelegt sind, sind jetzt rgba(0, 0, 0, 0.847).
Die berechneten Farbwerte stimmen auch im Dunkelmodus 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. In der Demo werden absichtlich die Verstöße gegen die WCAG AA und WCAG AAA mit den in der Warnung oben genannten Linkfarben dargestellt.

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