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 die themenspezifischen Standardeinstellungen des User-Agent-Stylesheets für ihre Seiten aktivieren.

Hintergrund

Die Medienfunktion mit den Nutzereinstellungen „prefers-color-scheme

Mit der Medienfunktion prefers-color-scheme in den Nutzereinstellungen haben Entwickler die volle Kontrolle über die Darstellung ihrer Seiten. Wenn du nicht damit vertraut bist, lies bitte meinen Artikel prefers-color-scheme: Hallo Dunkelheit, mein alter Freund, in dem ich alles dokumentiert habe, was ich über die Erstellung großartiger Effekte im dunklen Modus weiß.

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

Unterstützte Browser

prefers-color-scheme

Unterstützte Browser

  • 76
  • 79
  • 67
  • 12.1

Quelle

color-scheme

Unterstützte Browser

  • 81
  • 81
  • 96
  • 13

Quelle

Das User-Agent-Stylesheet

Bevor ich fortfahre, möchte ich kurz beschreiben, was ein User-Agent-Stylesheet ist. Meistens entspricht das Wort User-Agent (UA) dem Begriff Browser. Mit dem UA-Stylesheet wird das standardmäßige Design einer Seite festgelegt. Wie der Name schon sagt, hängt ein UA-Stylesheet von dem betreffenden UA ab. Sehen Sie sich das UA-Stylesheet von Chrome (und Chromium) an und vergleichen Sie es mit dem UA-Stylesheet von Firefox oder Safari (und WebKits). In der Regel sind sich UA-Stylesheets in den meisten Punkten einig. 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 und die Funktionen des dunklen Modus an. Führen Sie eine Volltextsuche nach „dark“ im Stylesheet durch. Die vom Stylesheet bereitgestellte Standardeinstellung hängt davon ab, ob der dunkle Modus aktiviert oder deaktiviert ist. Hier ist eine solche CSS-Regel, die die Pseudoklasse :matches und WebKit-interne Variablen wie -apple-system-control-background sowie die WebKit-interne Präprozessoranweisung #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 werden einige nicht standardmäßige Werte für die obigen Eigenschaften color und background-color bemerken. Weder text noch -apple-system-control-background sind gültige CSS-Farben. Es sind WebKit-interne semantische Farben.

Wie sich herausstellt, verfügt CSS über standardisierte semantische Systemfarben. Sie sind unter CSS-Farbmodulstufe 4 angegeben. Canvas (nicht zu verwechseln mit dem Tag <canvas>) dient beispielsweise für den Hintergrund von Anwendungsinhalten oder -dokumenten, während CanvasText für Text in Anwendungsinhalten oder -dokumenten steht. Beides geht zusammen und sollte nicht für sich allein 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 den folgenden CSS-Code 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
}

CSS-Eigenschaft color-scheme

Mit der Spezifikation Ebene 1 des CSS-Farbanpassungsmoduls werden ein Modell und Steuerelemente für die automatische Farbanpassung durch den User-Agent eingeführt, um Nutzereinstellungen wie den dunklen Modus, die Kontrastanpassung oder bestimmte gewünschte Farbschemas zu handhaben.

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. Folgende Werte werden derzeit unterstützt:

  • normal Gibt an, dass das Element keine Farbschemas erkennt und daher mit dem Standardfarbschema des Browsers gerendert werden sollte.

  • [ light | dark ]+ gibt an, dass das Element die aufgeführten Farbschemas erkennt und verarbeiten kann. Außerdem wird eine geordnete Präferenz zwischen ihnen ausgedrückt.

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

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 hierfür sind Bildlaufleisten, Unterstreichungen bei der Rechtschreibprüfung und Formularsteuerelemente.

Beim :root-Element muss das Rendering 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. Außerdem sollte sich das Rendering 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;
}

Das color-scheme-Meta-Tag

Damit das CSS-Attribut color-scheme berücksichtigt werden kann, muss das CSS zuerst heruntergeladen und geparst werden, wenn es über <link rel="stylesheet"> referenziert wird. Damit User-Agents den Seitenhintergrund mit dem gewünschten Farbschema sofort rendern können, kann in einem <meta name="color-scheme">-Element auch ein color-scheme-Wert 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 werden) zum gleichen Verhalten führen, empfehle ich, das Farbschema immer über das Meta-Tag anzugeben, damit der Browser das bevorzugte Schema schneller anwenden 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. Beispielsweise hat 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, ein unzureichendes Kontrastverhältnis von 2,23:1 auf schwarzem Hintergrund und nicht erfüllt die Anforderungen der WCAG AA und 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 CSS-Eigenschaft color-scheme und des entsprechenden Meta-Tags mit der Medienfunktion prefers-color-scheme der Nutzereinstellung kann auf den ersten Blick verwirrend wirken. Tatsächlich spielen sie wirklich gut zusammen. Das Wichtigste ist, dass Sie verstehen, dass color-scheme ausschließlich die Standarddarstellung bestimmt, während prefers-color-scheme die stilfähige Darstellung bestimmt. Nehmen wir zur Verdeutlichung folgende Seite:

<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. Wenn der Nutzer gemäß der Medienfunktion prefers-color-scheme der Nutzereinstellung ein dark-Farbschema bevorzugt, wird auf darkslategray gesetzt.

Über das <meta name="color-scheme" content="dark light">-Element 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 den hellen Modus eingestellt ist, erscheint die gesamte Seite je nach User-Agent-Stylesheet hell (im Dunkeln) oder umgekehrt. 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. Es ist entweder gainsboro oder darkslategray.

Eine Seite im hellen Modus.
Heller Modus:Vom Entwickler und vom User-Agent angegebene 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 User-Agent angegebene Stile. Gemäß dem User-Agent-Stylesheet ist der Text weiß und der Hintergrund schwarz. Das background-color des <fieldset>-Elements ist darkslategray gemäß dem Inline-Entwickler-Stylesheet.

Das Erscheinungsbild des <button>-Elements wird über das User-Agent-Stylesheet gesteuert. Für color ist die Systemfarbe ButtonText festgelegt und für background-color und die vier border-colors ist die Systemfarbe ButtonFace festgelegt.

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

Sehen Sie sich nun an, wie sich der border-color 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 je nach Farbschema dynamisch aktualisiert. Dasselbe gilt für color des <button>-Elements, für das die entsprechende Systemfarbe ButtonText festgelegt ist.

Sie zeigen, dass die berechneten Farbwerte zu ButtonFace passen.
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).
Zeigt, dass die berechneten Farbwerte im dunklen Modus weiterhin mit ButtonFace übereinstimmen.
Dunkler Modus: Die berechneten Werte von border-top-color und border-bottom-color, die beide im User-Agent-Stylesheet auf ButtonFace gesetzt sind, sind jetzt rgba(255, 255, 255, 0.847).

Demo

In einer Demo zu Glitch siehst du, wie sich color-scheme auf eine große Anzahl von HTML-Elementen auswirkt. Die Demo zeigt absichtlich den Verstoß gegen die WCAG AA und WCAG AAA mit den in der Warnung oben genannten Linkfarben.

Demo im hellen Modus.
Die Demo wurde zu color-scheme: light gewechselt.
Demo im dunklen Modus.
Die Demo wurde zu color-scheme: dark gewechselt. Beachte den Verstoß gegen die WCAG AA und WCAG AAA mit den Linkfarben.

Danksagungen

Die CSS-Eigenschaft color-scheme und das entsprechende Meta-Tag wurden von Rune Lillesveen implementiert. Rune ist außerdem Mitbearbeiter der CSS-Spezifikation für das Farbanpassungsmodul Level 1. Hero-Image von Philippe Leone auf Unsplash