Freitagnachmittag, eine kurze Kundenmail: „Können wir die Website eigentlich auch dunkel machen? Mein Handy stellt eh alles automatisch auf Dark Mode um, und die Seite leuchtet dann so grell." Vor zwei Jahren hätte das bei dir vermutlich ein leises Seufzen ausgelöst: eine zweite Farbpalette pflegen, ein Umschalt-Skript einbauen, auf jeder Unterseite testen, ob irgendwo weißer Text auf weißem Grund steht. Heute ist die ehrliche Antwort kürzer – „Ja, machen wir, und zwar ohne zusätzliches JavaScript." Denn Dark Mode ist 2026 zu einer Sache geworden, die der Browser größtenteils selbst erledigt.
Dieser Beitrag zeigt dir, wie du mit der CSS-Funktion light-dark() einen sauberen, barrierefreundlichen Dunkelmodus für Kundenseiten baust, warum du dafür kein Framework und keine Bibliothek mehr brauchst und wo die Stolperfallen liegen, wenn der Nutzer selbst umschalten können soll.
Dark Mode mit CSS: warum 2026 kein JavaScript mehr nötig ist
Lange war Dark Mode vor allem eine Fleißarbeit. Entweder du hast über die Media Query prefers-color-scheme zwei komplette Farbwelten gepflegt – einen hellen und einen dunklen Block, jeweils mit allen Farbwerten –, oder du hast eine JavaScript-Lösung eingebaut, die beim Laden eine CSS-Klasse auf das html-Element setzt. Beides funktioniert, aber beides erzeugt Aufwand: doppelte Pflege, zusätzliche Skripte, und bei der JS-Variante das berüchtigte kurze Aufblitzen der falschen Farben, bevor das Skript greift.
Seit Mai 2024 gibt es dafür eine native Alternative. Die CSS-Funktion light-dark() ist mit dem Erscheinen von Safari 17.5 in allen großen Browser-Engines angekommen und gilt seither als Baseline-Feature – also als Funktion, auf die du dich browserübergreifend verlassen kannst, nachdem zuvor schon Chrome 123 und Firefox sie unterstützten. Das ist der entscheidende Punkt: light-dark() ist kein Experiment mehr, sondern seit über zwei Jahren breit verfügbar. Für dich heißt das, du kannst es in Kundenprojekten einsetzen, ohne dir über Fallbacks für ältere Browser den Kopf zu zerbrechen.
Die Funktion macht genau das, was ihr Name verspricht: Sie nimmt zwei Werte entgegen – den ersten für den hellen, den zweiten für den dunklen Modus – und gibt je nach aktivem Farbschema den passenden zurück.
So funktioniert light-dark() in der Praxis
Damit die Funktion arbeiten kann, braucht sie eine Information: In welchen Modi darf sich die Seite überhaupt bewegen? Diese Information liefert die Eigenschaft color-scheme. Du setzt sie einmal zentral, üblicherweise auf dem Wurzelelement:
:root {
color-scheme: light dark;
}
Damit sagst du dem Browser zweierlei. Erstens: Diese Seite beherrscht beide Modi. Zweitens – und das wird gern übersehen – passt der Browser daraufhin auch seine eigenen Oberflächenelemente an, laut web.dev etwa Formularfelder, Scrollleisten und die Standard-Hintergrundfarbe. Du musst Checkboxen und Eingabefelder also nicht mehr mühsam selbst umfärben, damit sie im Dunkelmodus nicht wie Fremdkörper wirken.
Erst wenn color-scheme gesetzt ist, entfaltet light-dark() seine Wirkung. Ein typischer Einsatz sieht so aus:
:root {
color-scheme: light dark;
--hintergrund: light-dark(#ffffff, #1a1a1a);
--text: light-dark(#1a1a1a, #f2f2f2);
--akzent: light-dark(#0b5cab, #6cb6ff);
}
body {
background: var(--hintergrund);
color: var(--text);
}
Der Clou liegt in der Kombination mit CSS-Variablen. Du definierst deine Farben ein einziges Mal, jeweils als Paar aus Hell- und Dunkelwert, und verwendest überall im Projekt nur noch die Variable. Kein zweiter Media-Query-Block, keine doppelte Deklaration für jedes Element. Wenn der Kunde später eine Akzentfarbe geändert haben möchte, passt du eine einzige Zeile an – und sie wirkt in beiden Modi.
Der Unterschied zur alten prefers-color-scheme-Methode
Die Media Query prefers-color-scheme hat nicht ausgedient, sie löst nur eine andere Aufgabe. Sie prüft, ob das Betriebssystem des Nutzers auf hell oder dunkel steht, und erlaubt dir, ganze Regelblöcke daran zu knüpfen. Das bleibt sinnvoll, wenn im Dunkelmodus mehr passieren soll als nur ein Farbwechsel – etwa wenn du ein Logo austauschst oder einen Schatten entfernst, der auf dunklem Grund keinen Sinn ergibt.
Für die reine Farbgebung aber ist light-dark() deutlich schlanker. Wo du früher zwei Blöcke mit jeweils einem Dutzend Farbdeklarationen gepflegt hast, steht jetzt eine Zeile pro Farbe. Das reduziert nicht nur die Menge an Code, sondern auch die häufigste Fehlerquelle: dass du eine Farbe im einen Block änderst und im anderen vergisst.
Wenn der Nutzer selbst umschalten will
color-scheme: light dark folgt standardmäßig der Systemeinstellung des Nutzers. Das deckt die eingangs zitierte Kundenanfrage – „mein Handy ist eh im Dark Mode" – bereits vollständig ab, ganz ohne Schalter auf der Seite. Oft ist das die beste Lösung, weil sie die Entscheidung dort lässt, wo der Nutzer sie ohnehin schon getroffen hat.
Manche Kunden wollen trotzdem einen sichtbaren Umschalter. Auch das geht erstaunlich schlank. Du überschreibst color-scheme gezielt über ein Attribut am Wurzelelement, laut web.dev etwa so:
:root {
color-scheme: light dark;
}
:root[data-scheme="light"] { color-scheme: light; }
:root[data-scheme="dark"] { color-scheme: dark; }
Jetzt genügt eine einzige Zeile JavaScript, die beim Klick auf den Umschalter data-scheme auf "light" oder "dark" setzt – und light-dark() zieht automatisch die passenden Werte. Das ist weit weniger Code als eine klassische Theme-Umschaltung, bei der du jede betroffene Klasse manuell tauschst. Wichtig ist nur die Erwartung an den Kunden: Wer dauerhaft über das System hinaus umschalten und die Wahl beim nächsten Besuch erhalten möchte, braucht weiterhin eine kleine Speicherung der Präferenz. Der Farbmechanismus selbst bleibt aber reines CSS.
Barrierefreiheit nicht dem Zufall überlassen
Dark Mode ist kein rein kosmetisches Thema. Für manche Menschen – etwa mit Lichtempfindlichkeit oder bestimmten Sehbeeinträchtigungen – ist ein dunkler Modus eine echte Erleichterung, für andere ist gerade heller Text auf dunklem Grund schwerer zu lesen. Deshalb ist die Wahlfreiheit, die color-scheme: light dark dem Nutzer lässt, selbst schon ein Beitrag zur Zugänglichkeit.
Der Haken: Ein Farbpaar, das im hellen Modus genug Kontrast bietet, tut das im dunklen noch lange nicht. Ein mittelgraues Grau auf Weiß kann gut lesbar sein und auf Dunkelgrau trotzdem verschwimmen. Prüfe deshalb beide Modi getrennt gegen die Kontrastvorgaben der WCAG – mindestens das Verhältnis 4,5:1 für normalen Text. Das ist seit dem Barrierefreiheitsstärkungsgesetz für viele Kundenseiten ohnehin kein Kür-, sondern ein Pflichtthema geworden. Wie du Kontrast und andere Kriterien systematisch angehst, haben wir im Beitrag zur barrierefreien Website-Pflicht eingeordnet.
Was 2026 noch dazugekommen ist
light-dark() war ursprünglich auf Farbwerte beschränkt. Seit September 2026 akzeptiert die Funktion in Chrome, Firefox und Safari laut dem web.dev-Überblick auch Bildwerte – also URLs und Verläufe. Damit lässt sich etwa ein Hintergrundverlauf oder eine Grafik direkt pro Modus definieren, ohne den Umweg über zwei Media-Query-Blöcke:
body {
background-image: light-dark(
url("hero-hell.avif"),
url("hero-dunkel.avif")
);
}
Für Agenturen ist das mehr als eine Spielerei. Gerade Hero-Bilder, Illustrationen oder Verläufe, die im hellen Layout wirken, kippen im Dunkelmodus oft ins Unstimmige. Die Möglichkeit, pro Modus eine eigene Bildquelle zu hinterlegen, schließt diese Lücke mit derselben kompakten Syntax, die du schon für Farben nutzt. Dass der Browser immer mehr dieser früher JavaScript-lastigen Aufgaben selbst übernimmt, passt in ein größeres Bild – wir haben die wichtigsten dieser modernen CSS-Features gesammelt, mit denen sich schlankere, wartungsärmere Kundenseiten bauen lassen.
Fazit
Dark Mode ist 2026 kein Projektaufschlag mehr, den du lange kalkulieren musst, sondern eine Standardfähigkeit, die größtenteils im Browser steckt. Mit color-scheme: light dark gibst du dem Browser den Rahmen und lässt ihm die Oberflächenelemente, mit light-dark() definierst du Farben – und seit Kurzem auch Bilder – als kompaktes Hell-Dunkel-Paar statt als doppelten Regelsatz. Das Ergebnis ist weniger Code, weniger Pflegeaufwand und eine Fehlerquelle weniger. Den größten Teil der eingangs zitierten Kundenanfrage beantwortest du damit, ohne eine einzige Zeile JavaScript anzufassen. Der einzige Rest, für den sich noch ein kleines Skript lohnt, ist der manuelle Umschalter samt gespeicherter Präferenz – und selbst der ist nur noch ein Schatten dessen, was Dark Mode früher an Arbeit bedeutet hat.
- Die CSS-Funktion light-dark() ist seit Mai 2024 in allen großen Browsern verfügbar (Baseline) und ersetzt für die Farbgebung doppelte prefers-color-scheme-Blöcke durch ein kompaktes Hell-Dunkel-Paar pro Farbe.
- Voraussetzung ist die Eigenschaft color-scheme: light dark auf dem Wurzelelement – sie signalisiert dem Browser beide Modi und lässt ihn Formularfelder, Scrollleisten und Standardfarben automatisch anpassen.
- Ein manueller Umschalter braucht nur noch eine Zeile JavaScript, die ein data-scheme-Attribut setzt; der eigentliche Farbmechanismus bleibt reines CSS.
- Seit September 2026 akzeptiert light-dark() auch Bildwerte, sodass sich Hintergrundbilder und Verläufe pro Modus direkt in CSS definieren lassen.
- Beide Modi müssen getrennt auf Kontrast geprüft werden (mindestens 4,5:1 für normalen Text) – seit dem BFSG für viele Kundenseiten Pflicht, nicht Kür.