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

Hintergrund

Medienfunktion „prefers-color-scheme“ für Nutzereinstellungen

Mit der Medienfunktion prefers-color-scheme mit den Nutzereinstellungen haben Entwickler die volle Kontrolle über die Darstellung ihrer Seiten. Falls du damit nicht vertraut bist, lies meinen Artikel prefers-color-scheme: Hallo Dunkelheit, mein alter Freund, in dem ich alles dokumentiert habe, was ich über tolle Funktionen im dunklen Modus gelernt habe.

Ein Puzzleteil, das im Artikel nur kurz erwähnt wurde, sind die CSS-Eigenschaft color-scheme und das zugehörige Meta-Tag mit demselben Namen. Beide erleichtern Ihnen das Leben 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 verhindert diese Funktion, dass Browser 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

User-Agent-Stylesheet

Bevor ich fortfahre, möchte ich kurz beschreiben, was ein User-Agent-Stylesheet ist. Meist ist das Wort User-Agent (UA) einfach wie Browser zu verstehen. Mit dem UA-Stylesheet wird das Standarddesign einer Seite festgelegt. Wie der Name schon sagt, hängt ein UA-Stylesheet vom jeweiligen UA ab. Sie können sich das UA-Stylesheet von Chrome (und Chromium) ansehen und es mit dem von Firefox oder Safari (und dem WebKit) vergleichen. In der Regel stimmen UA-Stylesheets größtenteils überein. Links werden beispielsweise alle blau, der allgemeine Text schwarz und die Hintergrundfarbe weiß. Es gibt aber auch wichtige (und manchmal störende) Unterschiede, z. B. bei der Gestaltung von Formularsteuerelementen.

Sehen Sie sich das UA-Stylesheet von WebKit und seine Auswirkungen auf den dunklen Modus an. Führen Sie im Stylesheet eine Volltextsuche nach "dark" (dunkel) durch. Die vom Stylesheet bereitgestellte Standardeinstellung ändert sich je nachdem, ob der dunkle Modus aktiviert oder deaktiviert ist. Zur Veranschaulichung sehen Sie hier eine solche CSS-Regel, die die Pseudoklasse :matches und WebKit-interne Variablen wie -apple-system-control-background sowie die WebKit-interne Präprozessor-Anweisung #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 oben genannten 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 es aussieht, verwendet CSS standardisierte semantische Systemfarben. Sie sind im Abschnitt CSS-Farbmodul – Stufe 4 angegeben. Beispielsweise ist Canvas (nicht zu verwechseln mit dem Tag <canvas>) für den Hintergrund von Anwendungsinhalten oder -dokumenten vorgesehen, während CanvasText für Text in Anwendungsinhalten oder -dokumenten steht. Beides sollte zusammengehören und nicht isoliert verwendet werden.

Für UA-Stylesheets können entweder eigene oder standardisierte semantische 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 die folgenden 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-Eigenschaft color-scheme

In der Spezifikation CSS-Farbanpassungs-Modul Stufe 1 wird ein Modell eingeführt, mit dem die automatische Farbanpassung durch den User-Agent gesteuert wird. Dabei werden Nutzereinstellungen wie dunkler Modus, Kontrastanpassung oder bestimmte gewünschte Farbschemas berücksichtigt.

Mit der darin definierten color-scheme-Eigenschaft kann ein Element angeben, mit welchen Farbschemas es gerendert werden kann. Diese Werte werden mit den Einstellungen des Nutzers ausgehandelt, was zu einem ausgewählten Farbschema führt, das sich auf Elemente der Benutzeroberfläche (UI) auswirkt, 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 gar kein Farbschema erkennt. Daher sollte es mit dem Standardfarbschema des Browsers gerendert werden.

  • [ light | dark ]+ gibt an, dass das Element die aufgeführten Farbschemata kennt 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, dark das Gegenteil mit dunklen Hintergrundfarben und hellen Vordergrundfarben.

Durch das Rendern mit einem Farbschema sollten bei allen Elementen die Farben, die in der gesamten vom Browser bereitgestellten UI für das Element verwendet werden, dem Farbschema entsprechen. Beispiele hierfür sind Bildlaufleisten, Unterstreichungen bei der Rechtschreibprüfung und Formularsteuerelemente.

Beim :root-Element muss sich das Rendering mit einem Farbschema außerdem auf die Oberflächenfarbe des Canvas (d. h. die globale Hintergrundfarbe), den Anfangswert der color-Eigenschaft und die verwendeten Werte der Systemfarben auswirken. 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 Meta-Tag color-scheme

Um die CSS-Eigenschaft color-scheme zu berücksichtigen, muss der CSS-Code zuerst heruntergeladen werden (wenn über <link rel="stylesheet"> darauf verwiesen wird) und geparst werden. Damit User-Agents den Seitenhintergrund mit dem gewünschten Farbschema sofort rendern können, kann in einem <meta name="color-scheme">-Element 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) letztlich zum gleichen 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 Referenz sind keine zusätzlichen CSS-Regeln erforderlich. Im Allgemeinen sollten Sie jedoch color-scheme immer mit prefers-color-scheme kombinieren. Beispielsweise hat die proprietäre WebKit-CSS-Farbe -webkit-link, die von WebKit und Chrome für die klassische Link-Blau-rgb(0,0,238) verwendet wird, auf schwarzem Hintergrund ein unzureichendes Kontrastverhältnis von 2,23:1 und nicht erfüllt sowohl die WCAG AA als auch die Anforderungen der WCAG AAA.

Ich habe Fehler für Chrome, WebKit und Firefox sowie ein Metaproblem im HTML-Standard nachgereicht, um dieses Problem zu beheben.

Mit prefers-color-scheme interagieren

Das Zusammenspiel der CSS-Eigenschaft color-scheme und des entsprechenden Meta-Tags mit der Nutzereinstellung prefers-color-scheme kann auf den ersten Blick verwirrend wirken. Sie funktionieren sogar sehr gut zusammen. Wichtig ist zu verstehen, dass color-scheme ausschließlich die Standarddarstellung bestimmt, während prefers-color-scheme die stilierbare Darstellung bestimmt. Gehen Sie zur Verdeutlichung von der folgenden Seite aus:

<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 die background-color des <fieldset>-Elements im Allgemeinen auf gainsboro gesetzt und auf darkslategray, wenn der Nutzer ein dark-Farbschema gemäß der Medienfunktion prefers-color-scheme der Nutzereinstellungen bevorzugt.

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

Je nachdem, ob für das Betriebssystem der dunkle oder der helle Modus festgelegt ist, erscheint die gesamte Seite je nach User-Agent-Stylesheet hell auf dunkel oder umgekehrt. Es ist kein zusätzliches, vom Entwickler bereitgestelltes CSS erforderlich, um den Absatztext oder die Hintergrundfarbe der Seite zu ändern.

Wie sich das background-color-Element des <fieldset>-Elements ändert, hängt davon ab, ob der dunkle Modus aktiviert ist. Dabei werden die Regeln im vom Entwickler bereitgestellten Inline-Stylesheet auf der Seite befolgt. 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ß, entsprechend dem User-Agent-Stylesheet. Der background-color des <fieldset>-Elements ist entsprechend dem Inline-Entwickler-Stylesheet gainsboro.
Eine Seite im dunklen Modus.
Dunkler Modus:Vom Entwickler und vom User-Agent festgelegte Stile. Der Text ist weiß und der Hintergrund schwarz, entsprechend dem User-Agent-Stylesheet. Der background-color des <fieldset>-Elements ist entsprechend dem Inline-Entwickler-Stylesheet darkslategray.

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

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

Sehen Sie sich nun an, wie sich der border-color-Wert des <button>-Elements ändert. Der computed-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 basierend auf dem Farbschema dynamisch aktualisiert. Dasselbe gilt für color des <button>-Elements, für das die entsprechende Systemfarbe ButtonText festgelegt ist.

Sie sehen, dass die berechneten Farbwerte mit ButtonFace übereinstimmen.
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).
Anzeige, dass die berechneten Farbwerte auch im dunklen Modus 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

Die Auswirkungen von color-scheme auf eine große Anzahl von HTML-Elementen kannst du in einer Demo zu Glitch sehen. In der Demo werden absichtlich die Verstöße der WCAG AA und der WCAG AAA mit den in der Warnung oben angegebenen 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 geändert. Beachte den Verstoß der WCAG AA und der WCAG 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 Spezifikation des CSS-Farbanpassungsmoduls – Stufe 1. Hero-Image von Philippe Leone auf Unsplash