Dark Mode und Systemschriften

Ich schiebe es jetzt schon eine ganze Weile vor mir her, endlich einen Dark Mode für diese Website einzubauen. Ich habe mehrere Male angefangen, mit der neuen Media Query prefers-color-scheme zu experimentieren. Nur habe ich es nie wirklich zu Ende gebracht. Ich habe auch überlegt, ob nicht so ein kleiner Schalter (z. B. mit Darkmode.js) ganz nett wäre, damit man selbst zwischen hell und dunkel umschalten kann.

Ich möchte meine Website aber so frei von JavaScript halten wie möglich. Die Idee mit dem Button habe ich deshalb schnell verworfen. Möglichkeiten, das ohne JavaScript umzusetzen, gibt es aktuell nicht.

Die Website sollte sich aber schon ein wenig danach richten, was der Besucher gerne möchte. Dafür gibt es schon länger die Media Query prefers-color-scheme. Damit kann man im Stylesheet abfragen, was der Besucher in seinem System bzw. Browser eingestellt hat: Möchte ich lieber den Dark Mode oder den Light Mode? Je nach Einstellung kann man mit der Media Query dann darauf reagieren und die Website entsprechend anzeigen.

/* Standard-Einstellungen */
body {
    background: white;
    color: black;
}

/* 
 * Wenn der Besucher gerne einen Dark Mode hätte, 
 * überschreibt das hier den Standard. 
 */
@media (prefers-color-scheme: dark) {
    body {
        background: black;
        color: white;
    }
}

Ich hatte nur gedacht, dass das für meine Website etwas kompliziert werden könnte. Ich benutze Bootstrap Reboot, damit die Website möglichst einheitlich auf verschiedenen Geräten und Browsern aussieht. Reboot setzt deswegen auch für einige Elemente schon Farben. Außerdem bleibt es nicht bei einem einfachen Ändern der Vorder- und Hintergrundfarbe. Für einen vernünftigen Kontrast müssen auch die Farben von Hyperlinks, Codeschnipseln und leicht abgesetzten Elementen (z. B. das Datum bei Blogposts) geändert werden.

Am Ende war das dann aber doch nicht so kompliziert. Um nicht verschiedene Stylesheets für die beiden Farbmodi bauen und laden zu müssen, habe ich CSS-Variablen für die Farben genutzt, z. B. für die Farbe der Links. Die Farben werden global (im Pseudo-Element :root) definiert. Hier wird schon entschieden, ob wir im Dark oder Light Mode sind. Der Rest vom CSS benutzt dann nur noch die fertigen Variablen, die sich ja schon richtig auf den Farbmodus eingestellt sind.

:root {
    --color-background: #fff;
    --color-foreground: #212529;
    --color-link: #0071F0;
    --color-link-hover: #004da4; 
}

@media (prefers-color-scheme: dark) {
    :root {
        --color-background: #343a40;
        --color-foreground: #f8f9fa;
        --color-link: #7bbbff;
        --color-link-hover: #2f94ff; 
    }
}

body {
    background: var(--color-background);
    color: var(--color-foreground); 
}

a {
    color: var(--color-link); 
}

a:hover {
    color: var(--color-link-hover); 
}

Das habe ich dann auch für den Rest aller gefärbten Elemente durchgezogen. Für die Codebeispiele wird je nach Farbmodus dann ein anderes Theme für Pygments geladen.

Außerdem habe ich noch eine Anpassung zurückgenommen: Ich habe die Schriftart wieder auf die Standardeinstellung von Bootstrap Reboot zurückgestellt. Dadurch werden jetzt die nativen Systemschriften verwendet. Bei Windows ist das z. B. Segoe UI, auf OS X und iOS die Schrift San Francisco und auf Android Roboto.