10 Punkte von GN⁺ 10 일 전 | 1 Kommentare | Auf WhatsApp teilen
  • Von Browser-Bordmitteln bis zu JavaScript-Media-Queries: eine Einordnung in 8 Stufen, die den Umfang der Dark-Mode-Implementierung schrittweise erweitert
  • Die einfachste Variante besteht nur aus der Deklaration <meta name="color-scheme" content="light dark"> oder color-scheme: light dark und folgt damit der bevorzugten Farbgebung des Nutzers
  • Auf höheren Stufen erlauben die Funktion light-dark(), @media (prefers-color-scheme: dark) und separate Stylesheets pro Schema weitreichende Anpassungen nicht nur bei Farben, sondern auch bei Bildern und Schatten
  • Statt nur den Systemeinstellungen des Nutzers zu folgen, lässt sich ein Umschalter mit den drei Optionen Automatic·light·dark bereitstellen; mit :has() und dem tatsächlichen meta-Element kann das Theme erkannt werden
  • Einschließlich der Barrierefreiheitsgrenzen von Safari und Beobachtungen zum Verhalten von prefers-color-scheme beim Drucken zeigt sich, dass sich Light- und Dark-Mode inzwischen schon mit aktuellen CSS-Funktionen leicht integrieren lassen

Stufenweise Implementierung von Dark Mode

  • Level 1: Barebone

    • Auch ohne eine einzige Zeile CSS lässt sich die Unterscheidung zwischen light und dark aktivieren: Es genügt, im head des Dokuments <meta name="color-scheme" content="light dark"> hinzuzufügen, und der Browser beginnt, der bevorzugten Farbgebung des Nutzers zu folgen
    • Die Reihenfolge der Einträge im Attribut content hat theoretisch eine Bedeutung: Nutzer ohne explizite Präferenz für ein Farbschema erhalten den ersten Wert in der durch Leerzeichen getrennten Liste
    • Da aktuelle Betriebssysteme keine Option bieten, gar kein Farbschema zu wählen, läuft es praktisch auf das Schema hinaus, das der Betriebssystemeinstellung entspricht
    • Im content kann auch nur ein einzelner Wert angegeben werden; in diesem Fall wird dieses Schema erzwungen, unabhängig von Nutzerpräferenzen
    • Dieses Meta-Tag übernimmt gewissermaßen die HTML-seitige Entsprechung zum CSS-Ansatz der nächsten Stufe
  • Level 2: Basic

    • In CSS lässt sich die Unterscheidung zwischen Light und Dark Mode mit der Deklaration html { color-scheme: light dark; } aktivieren
    • Ist bereits ein Meta-Tag im DOM vorhanden, ist diese Deklaration nicht nötig; wenn man das HTML kontrollieren kann, wird das Meta-Tag empfohlen, weil der Browser die Anweisung schon vor dem Parsen des CSS kennt
    • Beide Wege erlauben es, die Standardstile des User Agent und den darin enthaltenen Light-/Dark-Mode zu nutzen
    • Ergänzt man hier CSS und beschränkt sich dabei vor allem auf CSS system colors, lässt sich bereits ein ziemlich aufgeräumtes Design umsetzen
    • Anders als das Meta-Tag, das immer für das gesamte Dokument gilt, kann die CSS-Deklaration color-scheme auch an anderen Stellen als dem Wurzelelement gesetzt werden; daraus ergeben sich zusätzliche Einsatzmöglichkeiten
  • Level 3: Benign

    • Mit der noch relativ neuen CSS-Farbfunktion light-dark() lassen sich einfache Anpassungen für Light und Dark Mode vornehmen
    • Im Beispiel wird sie wie background-color: light-dark(black, white); und color: light-dark(white, black); verwendet; das erste Argument gilt im Light Mode, das zweite im Dark Mode
    • Als Argumente können direkte Farben eingesetzt werden, aber auch custom properties, die als Farben interpretiert werden
    • Im gesamten Artikel hat nur diese Stufe zum Zeitpunkt der Veröffentlichung noch keine ausreichende Browser-Unterstützung
  • Level 4: Bold

    • Mit der klassischen Media Query @media (prefers-color-scheme: dark) lässt sich das Umschalten auf Dark Mode umsetzen
    • Unabhängig davon, ob light oder dark abgefragt wird, ist damit das größtmögliche Maß an Anpassung möglich, das nicht auf einfache Farbwechsel beschränkt ist
    • So lassen sich im Dark Mode etwa Bilder per Filter entsättigen oder Box-Shadows durch Outlines ersetzen
  • Level 5: Bisectional

    • Media Queries lassen sich auch in HTML verwenden, indem man sie in das Attribut media eines link-Elements setzt und so Stylesheets pro Schema trennt
    • Gezeigt wird ein Ansatz, bei dem light.css und dark.css jeweils mit prefers-color-scheme: light und prefers-color-scheme: dark verknüpft werden
    • Wenn der Umfang der Anpassungen groß ist, eignet sich eine Struktur mit eigenen Dateien; außerdem kann der Browser CSS-Dateien ignorieren, die nicht zur Query passen, sodass möglicherweise eine Datei weniger heruntergeladen wird
  • Level 6: Ballistic

    • In JavaScript lässt sich die Media Query für Farbschemata mit window.matchMedia('(prefers-color-scheme:dark)') verwenden
    • Wie bei anderen Media Queries kann man abfragen, ob ein Light- oder Dark-Schema aktiv ist, und auf dieser Grundlage beliebige Verarbeitung ausführen
    • In realen Implementierungen müssen die Techniken der vorigen Stufen nicht isoliert verwendet werden, sondern können kombiniert werden

Nutzer-Umschalter und fortgeschrittene Muster

  • Level 7: Beyond

    • Man muss sich nicht ausschließlich auf die Systempräferenz des Nutzers verlassen, sondern kann einen color scheme switcher bauen
    • Dieser Umschalter ist kein simples Boolean, denn als anfänglicher Standardwert wird ein Automatic-Modus benötigt, der prefers-color-scheme folgt
    • Legt man darauf einen Umschalter, kann der Nutzer zwischen den drei Modi Automatic, light und dark wählen
  • Level 8: Beguiling

    • Bei der Umsetzung des Umschalters aus Level 7 ist es üblich, einem HTML-Element eine Klasse wie .dark oder ein Attribut wie data-theme="dark" hinzuzufügen
    • Stattdessen kann mit :has() direkt die Existenz von <meta name="color-scheme" content="dark"> abgefragt werden
    • Im Beispiel werden unter dem Selektor html:has(meta[name="color-scheme"][content="dark"]) CSS-Variablen wie --color-bg und --color-text auf Werte für den Dark Mode gesetzt
    • So lässt sich das Theme auch ohne separate Klasse oder Datenattribut anhand des tatsächlichen meta-Elements erkennen

Zusätzliche Diskussionen und Beobachtungen

  • Beobachtungen zum CSS Naked Day

    • Nach dem Entfernen von Styles fiel bei fast allen besuchten Websites das Fehlen eines Dark Mode auf, was zur Einteilung in verschiedene Dark-Mode-Stufen führte
    • Beim Neuaufbau einer Website und dem Schreiben frischer Styles wird erwähnt, dass sich mit aktuellen CSS-Funktionen Light und Dark Mode direkt eingebaut sehr leicht umsetzen lassen
  • Safari-Barrierefreiheitsprobleme

    • Es wird darauf hingewiesen, dass Safari bis vor relativ kurzer Zeit im Dark Mode keine barrierefreien Linkfarben bereitstellte
    • Beim vorherigen CSS Naked Day wurde dieses Problem entdeckt, daraufhin das Meta-Tag entfernt und nur ein helles Farbschema verwendet
    • Später wurde das Meta-Tag wieder hinzugefügt, allerdings in dem Bewusstsein, dass es für Nutzer älterer Safari-Versionen zu verschlechterter Barrierefreiheit kommen kann
    • Außerdem wurde festgestellt, dass Textfelder im Dark Mode von Safari keinen sichtbaren Rahmen haben
    • Selbst mit den Standardstilen des User Agent und korrekt verwendetem semantischem HTML ist vollständige Barrierefreiheit nicht garantiert; deshalb wird darüber nachgedacht, auch bei künftigen CSS Naked Days ausreichend Styling beizubehalten
  • Drucken und die Bedingung screen and

    • Als Grund für die Verwendung von screen and ... im Beispiel zu Bisectional wird genannt, dass Drucker ausgeschlossen werden sollten
    • Dabei wird davon ausgegangen, dass es ein themenunabhängiges Core-Stylesheet oder ein eigenes Druck-Stylesheet gibt; da Dark Mode auf Druckern viel Tinte verbrauchen könnte, sollte dies vorsichtshalber getrennt werden
    • In tatsächlichen Tests wurde selbst bei aktivem systemweiten Dark Mode nur schwarzer Text auf weißem Papier gedruckt; beobachtet wurde also, dass Browser diese Dark-Mode-Styles beim Drucken nicht anwenden
    • In weiteren Tests wurde in der Druckvorschau prefers-color-scheme immer als light gemeldet; bestätigt wurde das in Firefox und Chromium
    • Abschließend gibt es die scherzhafte Bemerkung, es wäre schade für den Fall, dass jemand einen Drucker mit schwarzem Papier und weißer Tinte besitzt

1 Kommentare

 
GN⁺ 10 일 전
Hacker-News-Kommentare
  • Wenn man viel customizt, ist eine eigene Datei zwar nachvollziehbar, aber die Erklärung, dass per Media Query nicht passende CSS gar nicht erst heruntergeladen würden, entspricht meiner Meinung nach nicht dem tatsächlichen Browser-Verhalten. Meiner Erfahrung nach laden Browser am Ende alles herunter und gewichten nur die Priorität unterschiedlich
  • Ich habe mich gefragt, ob es immer noch keine Möglichkeit gibt, dieses Flashbang-artige Aufblitzen zu verhindern, das entsteht, während man auf den initialen Inhalt vom Server wartet
    • Ich halte es für eine brauchbare Lösung, in Firefox in userContent.css die background-color festzulegen
    • Ich habe einfach die Bildschirmhelligkeit reduziert und den Dark Mode ausgeschaltet, dann war das Flashbang weg. Als Bonus hält auch der Akku länger
  • Ich dachte, in diesem Artikel ginge es um Vorlieben bei der Schwärze des Dark-Mode-Hintergrunds. Ich habe auch gehört, dass reines Schwarz auf OLEDs batterieeffizienter ist, und ich kenne Leute, die ein weniger tintenartiges Grau lieber mögen als vollkommenes Schwarz. Ob man dafür unbedingt sechs Stufen braucht, weiß ich allerdings nicht; für spürbar halte ich höchstens etwa 3 bis 4 Stufen
    • Ich dachte, die allgemeinere Lösung wäre die Standardisierung der Kompatibilität mit dem Reader Mode. Statt eines n-x-m-Problems, bei dem jede Website jede einzelne Nutzerpräferenz bedienen muss, wäre eine Struktur besser, bei der die Website nur eine einfache Inhaltsansicht unterstützt und der Browser darauf aufbauend die nutzerspezifischen Einstellungen übernimmt
    • Auf OLEDs bevorzuge ich reines Schwarz. Ich habe das Gefühl, dass weniger aktivierte Pixel die Burn-in-Belastung senken, und da die Lebensdauer ohnehin begrenzt ist, würde ich einen Monitor langfristig lieber 5 Jahre oder länger statt nur 2 bis 3 Jahre nutzen
  • Für mich ist die höchste Stufe 9, oder sonst 0: einfach den Computer ausschalten und schlafen gehen
  • Ich fand es gut, dass der OP den 3-Zustände-Toggle ordentlich umgesetzt hat
  • Ich hätte es noch interessanter gefunden, wenn die Stufen beim Herunterscrollen dynamisch angewendet worden wären
    • Oder man hätte den Lesern an passenden Stellen auf der Seite selbst die Stufe wählen lassen können
  • Meiner Meinung nach sind es eher 8 Stufen
  • Das fühlte sich sehr nach 2024 an
  • In dieser Situation musste ich natürlich sofort an xkcd 3227 denken