Mit einem Schalter für den dunklen Modus können Nutzer das Farbschema des Systems für eine Website überschreiben.
Die Überschreibung wird durch Aktualisieren von <meta name="color-scheme"> angewendet: light dark bedeutet „Systemeinstellung folgen“, light oder dark legt ein explizites Schema fest.
Farben (light-dark()), Systemfarben und die native Benutzeroberfläche hängen alle von der CSS-Eigenschaft color-scheme ab. Die Ein/Aus-Schaltfläche funktioniert also, indem diese Eigenschaft mit dem <meta> synchronisiert wird (siehe Überschreibung in CSS widerspiegeln).
Dauerhafte Ein/Aus-Schaltfläche, Einstellung oder gar keine Ein/Aus-Schaltfläche?
Die meisten Websites benötigen keine dauerhafte Farbschema-Umschaltfläche in der Benutzeroberfläche der Website (Header, Navigation, Footer usw.). Folge standardmäßig der Systemeinstellung. Wenn eine manuelle Überschreibung erforderlich ist, platziere das Steuerelement in einer separaten Einstellungsoberfläche: einer Einstellungsseite, einem Steuerfeld oder einem Overlay.
Das Anpinnen eines Schemas an das Betriebssystem ist ein legitimer, aber seltener Anwendungsfall. Solche seltenen Anwendungsfälle gehören hinter eine progressive Offenlegung und nicht in ein Steuerelement, das immer sichtbar ist.
Dauerhafte Schalter finden sich meist auf Websites für Entwickler oder Entwickler-nahe Personen (z.B. Designer), bei denen das Wechseln des Farbschemas weitaus häufiger vorkommt als bei durchschnittlichen Web-Nutzern. Fügen Sie KEINE hinzu, nur weil es ein gängiges Muster auf Entwicklerwebsites ist: Das Interesse des Entwicklers an diesem Steuerelement ist nicht repräsentativ für typische Nutzer.
Implementierung
Folgen Sie zuerst allen Schritten unter Dunkler Modus, um beide Schemas zu unterstützen. Standardmäßig wird die Systemeinstellung verwendet.
Datenmodell
Das Datenmodell für den Schalter für den dunklen Modus umfasst in der Regel drei Zustände:
- System (kein gespeicherter Wert): Die Benutzeroberfläche folgt dem Farbschema des Systems. Idealerweise sollte dies die Standardeinstellung sein.
- Hell (gespeichert als
"light"): Die Benutzeroberfläche verwendet das helle Design, unabhängig vom Farbschema des Systems. - Dunkel (gespeichert als
"dark"): Die Benutzeroberfläche verwendet das dunkle Design unabhängig vom Farbschema des Systems.
Dieser Status wird normalerweise in localStorage gespeichert und in einem <meta name="color-scheme">-Element im Dokumentkopf widergespiegelt.
Überschreibung im CSS-Code widerspiegeln
Das <meta> ist nur ein Darstellungshinweis: Jede color-scheme-Deklaration im CSS des Autors überschreibt es.
Da im dunklen Modus color-scheme: light dark auf :root gesetzt wird, ist das Aktualisieren von <meta> allein ein No-Op – CSS hat Vorrang.
Ordnen Sie <meta> wieder der Property zu, damit die Kaskade ihr folgt:
:root {
color-scheme: light dark;
&:has(> head > meta[name="color-scheme"][content="dark"]) {
color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="light"]) {
color-scheme: light;
}
}
NICHT color-scheme: light oder color-scheme: dark als Standard-Stammverzeichnis hartcodieren; die Basisdeklaration MUSS light dark bleiben.
CSS DARF NICHT von JS abhängig sein: Wenn JS nie ausgeführt wird, bleibt <meta> auf light dark und die Website folgt der Systemeinstellung – es kommt zu keinen Fehlern.
Persistenz und FOUC-Prävention
Behalten Sie die Überschreibung in localStorage bei. Entfernen Sie den Eintrag, wenn Sie zur Systemstandardeinstellung zurückkehren.
Damit nicht kurz das falsche Farbschema angezeigt wird, wenden Sie den gespeicherten Wert in einem Inline-Script (NICHT type=module, NICHT defer) an, das direkt nach dem <meta>-Element platziert wird:
<meta name="color-scheme" content="light dark">
<script>
document.querySelector('meta[name="color-scheme"]').content = localStorage.getItem("color-scheme") ?? "light dark";
</script>
- Dieses Inline-Script dient nur dazu, FOUC zu verhindern. Halten Sie es so klein wie möglich. Zusätzliches JS für die Verarbeitung des Farbschemawechsels kann später geladen werden.
- In seltenen Fällen kann der Zugriff auf
localStorageeinen Fehler auslösen (z. B. wenn Websitedaten blockiert sind). Da dieses Script jedoch nichts anderes tut, wäre die einzige Nebenwirkung ein Konsolenfehler. Verwenden Sietry .. catch, wenn dies wichtig ist. Das Design muss weiterhin auf die Seite angewendet werden, auch wenn es nicht beibehalten werden kann. - Die Überschreibung kann sich von einem anderen Tab aus ändern: Verarbeite das
storage-Ereignis vonwindow, um die Synchronisierung aufrechtzuerhalten. - Verwende NICHT
matchMedia(), um den gespeicherten Wert zu entfernen, wenn sich die Systemeinstellung ändert und mit ihm übereinstimmt. Bei vielen Nutzern wechselt das Betriebssystem automatisch je nach Tageszeit das Farbschema. Wenn der gespeicherte Wert jedes Mal entfernt würde, wenn die beiden Werte zufällig übereinstimmen, wäre es unmöglich, ein Farbschema festzulegen.
Verzweigung für HTML- und Nicht-Farbwerte
Farben erfordern keinen zusätzlichen Aufwand: Sobald <meta> color-scheme zugeordnet ist (siehe oben), folgt light-dark() der Überschreibung.
In diesem Abschnitt geht es um die Anpassung anderer Werte (z.B. font-weight, Medienquellen usw.).
Wenn die Seite einfach der Systemeinstellung folgt, kann (prefers-color-scheme: dark) für die Verzweigung verwendet werden, auch in <picture>- oder <video>-Quellen.
Das Überschreiben des Farbschemas bringt eine zusätzliche Komplikation mit sich: Die Systemeinstellung ist nicht mehr die einzige Informationsquelle und für APIs, die nur Medienabfragen akzeptieren, gibt es keine direkte Alternative.
Verlassen Sie sich für die Verzweigung NICHT ausschließlich auf JS-angewendete Klassen wie .dark, da diese falsch sind, wenn JS nicht geladen wird und das Betriebssystem standardmäßig dunkel ist.
Sie können die Medienabfrage mit einem :root:has(> head > meta[name="color-scheme"][content="dark"])- (oder light-)Selektor kombinieren, um eine Verzweigung zu erstellen.
Weitere Informationen zur eleganten Implementierung finden Sie unter Selector & @-rule Combinations.
Die Optionen des Steuerelements sind ebenfalls nicht farbbezogene Verzweigungen: Beide Zustände werden im Markup angegeben (Symbol plus visuell ausgeblendeter Aktionstext, z.B. „Zum dunklen Design wechseln“) und der inaktive Zustand wird über diese Selektoren ausgeblendet.
display: none entfernt auch die redundante Option aus der AT, sodass das Steuerelement kein JS benötigt, um auf dem neuesten Stand zu bleiben, wenn sich die Systemeinstellung ändert.
Bei In-HTML-Medien besteht die einzige Möglichkeit derzeit darin, beide Versionen als separate Elemente einzufügen und die Sichtbarkeit entsprechend umzuschalten.
Das Ausblenden von <source>-Elementen mit display: none funktioniert nicht.
Benutzeroberfläche
Zwei oder drei Bundesstaaten?
In jedem Fall MUSS die Benutzeroberfläche das Zurücksetzen oder Festlegen des Farbschemas auf das System unterstützen.
Bei platzbeschränkten Ein/Aus-Schaltflächen, z. B. dauerhaften Ein/Aus-Schaltflächen in der Website-Chrome (Header, Navigation, Footer usw.), wo der Platz begrenzt ist und das Anpassen von Einstellungen in der Regel nicht dem Ziel des Nutzers entspricht, sollten zwei Zustände angezeigt werden.
Eine Farbschema-Steuerung in einer separaten Einstellungsoberfläche (Seite, Bereich oder Overlay) ist ein anderes Szenario und KANN alle drei Zustände explizit anzeigen („Hell“, „Dunkel“, „System“): Dort trifft der Nutzer bereits bewusste Entscheidungen über das zukünftige Verhalten und es gibt Platz, um die Optionen zu erklären.
Drei explizite Zustände sind auch dann gerechtfertigt, wenn die Website kontextsensitive Schemata implementiert (z.B. einen gedimmten hellen Modus, wenn das Betriebssystem dunkel ist), da sich „Hell“ und „System (derzeit hell)“ dann tatsächlich unterscheiden.
Umschalter mit zwei Zuständen
Wenn ein solches Steuerelement verwendet wird, handelt es sich in der Regel um eine vorübergehende Anpassung des Komforts („Es ist gerade zu hell“), und nicht um eine langfristige Beibehaltung des aktuellen Zustands. Daher reicht es bei Schaltern mit zwei Zuständen aus, zwei von drei Einstellungen anzuzeigen: „System“ (damit die Einstellung zurückgesetzt werden kann) und das aktuelle Gegenteil von „System“, das als aktueller Literalwert gespeichert ist.
Die einzigen beiden Status sollten sein:
- System-Standardeinstellung: kein gespeicherter Wert,
<meta>-Inhaltlight dark. Wird als aktueller aufgelöster Wert angezeigt (z.B. ein Sonnensymbol, wenn es hell ist). - Überschreiben: Wird buchstäblich als
lightoderdarkgespeichert.
Im Grunde handelt es sich um ein Steuerelement mit drei Zuständen (light dark, light, dark), bei dem der explizite Zustand, der der aktuellen Systemeinstellung entspricht, nicht erreichbar ist.
Wenn der Nutzer die Einstellung aktiviert:
- Zielschema = das Gegenteil des aktuell gerenderten Schemas (gespeicherter Wert, falls vorhanden, andernfalls Systemeinstellung). Die Nutzerabsicht ist „das Gegenteil von dem auswählen, was ich gerade sehe“, NICHT „das Gegenteil der Systemstandardeinstellung auswählen“.
- Wenn das Ziel von der aktuellen Systemeinstellung abweicht, speichern Sie es wortgetreu.
- Wenn das Ziel mit der aktuellen Systemeinstellung übereinstimmt, macht der Nutzer seine Anpassung rückgängig: Der gespeicherte Wert wird entfernt. Speichern Sie es NICHT, da das Schema sonst unsichtbar gegen zukünftige Systemänderungen gesperrt wird.
- Legen Sie den Inhalt von
<meta>auf den gespeicherten Wert oder auflight darkfest, wenn kein Wert vorhanden ist.
WICHTIG: Abweichungen dürfen nur zum Zeitpunkt der Speicherung geprüft werden, niemals rückwirkend. Ein gespeicherter Wert, der später mit der Systemeinstellung übereinstimmt, MUSS beibehalten werden. Bei vielen Nutzern wechselt das Betriebssystem automatisch je nach Tageszeit das Farbschema. Wenn der gespeicherte Wert jedes Mal entfernt würde, wenn die beiden Werte zufällig übereinstimmen, wäre es unmöglich, ein Farbschema festzulegen.
Beispielszenario, beginnend mit dem Betriebssystem im hellen Modus:
- Der Nutzer schaltet die Option ein. „Dunkel“ unterscheidet sich von der Systemeinstellung, daher wird
darkgespeichert und die Website wird dunkel. - Die Betriebssystemeinstellung wird in „Dunkel“ geändert. Die Website bleibt dunkel (der gespeicherte Wert entspricht jetzt der Systemeinstellung, wird aber beibehalten).
- Die Betriebssystemeinstellung wird wieder auf „Hell“ zurückgesetzt. Die Website bleibt dunkel.
- Der Nutzer aktiviert die Option. Das Ziel (hell) entspricht der Systemeinstellung, sodass der gespeicherte Wert entfernt wird und die Website wieder der Systemeinstellung folgt.
Umschaltflächen mit drei Zuständen
Wenn mehr Platz vorhanden ist und Nutzer bereits die Absicht haben, langfristige Einstellungen festzulegen, kann eine dreistufige Einstellung für mehr Klarheit sorgen. In diesem Fall wird das Datenmodell sauber den drei UI-Optionen zugeordnet: System, Hell und Dunkel.
Um die kognitive Belastung zu reduzieren, sollte die Option „System“ auch die aktuelle Systemeinstellung anzeigen, z. B. über:
- Symbol, z.B. ein Sonnensymbol rechts unten neben dem Systemsymbol
- Text, z.B. „System (derzeit hell)“