Back

So erstellen Sie einen Dark-Mode-Umschalter mit CSS und JavaScript

So erstellen Sie einen Dark-Mode-Umschalter mit CSS und JavaScript

Dark Mode ist für moderne Websites unverzichtbar geworden. Benutzer erwarten, dass sie Themes basierend auf ihrer Umgebung, der Tageszeit oder persönlichen Vorlieben wechseln können. Dieses Tutorial zeigt Ihnen, wie Sie einen robusten Dark-Mode-Umschalter erstellen, der Systemeinstellungen respektiert, Benutzerauswahl speichert und moderne CSS-Features für optimale Performance nutzt.

Wichtigste Erkenntnisse

  • Erstellen Sie einen Dark-Mode-Umschalter, der Systemeinstellungen respektiert und Benutzerauswahl persistent speichert
  • Nutzen Sie CSS Custom Properties und die color-scheme-Eigenschaft für effizientes Theming
  • Implementieren Sie JavaScript, das ein Flash of Unstyled Content beim Seitenladen verhindert
  • Wenden Sie Best Practices für Barrierefreiheit bei Tastaturnavigation und Screenreadern an

Einrichten der HTML-Struktur

Beginnen Sie mit semantischem HTML, das einen Toggle-Button enthält und das initiale Theme deklariert:

<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="color-scheme" content="light dark">
    <title>Dark Mode Toggle Demo</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <button type="button" id="theme-toggle" aria-label="Toggle dark mode">
        <span class="toggle-text">Dark</span>
    </button>
    <!-- Your content here -->
</body>
</html>

Das data-theme-Attribut am HTML-Element steuert unser Theme. Das color-scheme-Meta-Tag teilt dem Browser mit, native UI-Elemente wie Scrollbars und Formularelemente anzupassen.

CSS-Implementierung mit modernen Features

Verwendung von CSS Custom Properties und color-scheme

Definieren Sie Ihre Farb-Tokens mit CSS Custom Properties und nutzen Sie dann die CSS-Eigenschaft color-scheme für natives Element-Theming:

:root {
    color-scheme: light dark;
    
    /* Light theme colors (default) */
    --bg-color: #ffffff;
    --text-color: #213547;
    --accent-color: #0066cc;
}

[data-theme="dark"] {
    --bg-color: #1a1a1a;
    --text-color: #e0e0e0;
    --accent-color: #66b3ff;
}

body {
    background-color: var(--bg-color);
    color: var(--text-color);
    transition: background-color 0.3s ease, color 0.3s ease;
}

Systemeinstellungen mit prefers-color-scheme respektieren

Fügen Sie Unterstützung für prefers-color-scheme hinzu, um automatisch die Systemeinstellungen zu übernehmen:

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg-color: #1a1a1a;
        --text-color: #e0e0e0;
        --accent-color: #66b3ff;
    }
}

Die moderne light-dark()-Funktion

Für Browser, die die light-dark()-Funktion unterstützen, können Sie Farbdefinitionen vereinfachen:

:root {
    color-scheme: light dark;
}

body {
    background-color: light-dark(#ffffff, #1a1a1a);
    color: light-dark(#213547, #e0e0e0);
}

Diese Funktion wählt automatisch die passende Farbe basierend auf dem aktiven Color Scheme aus und reduziert Code-Duplikation.

JavaScript für Toggle und Persistenz

Theme-Flash beim Laden verhindern

Platzieren Sie dieses Script unmittelbar nach dem öffnenden <body>-Tag, um Flash of Unstyled Content zu verhindern:

<script>
    // Apply saved theme immediately to prevent flash
    (function() {
        const saved = localStorage.getItem('theme');
        if (saved) {
            document.documentElement.setAttribute('data-theme', saved);
        } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
            document.documentElement.setAttribute('data-theme', 'dark');
        }
    })();
</script>

Vollständige Dark-Mode-Implementierung

Fügen Sie dieses JavaScript für die Toggle-Funktionalität hinzu:

const toggle = document.getElementById('theme-toggle');
const html = document.documentElement;

// Get current theme
function getTheme() {
    return html.getAttribute('data-theme') || 
           (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
}

// Set theme and update UI
function setTheme(theme) {
    html.setAttribute('data-theme', theme);
    localStorage.setItem('theme', theme);
    updateToggleText(theme);
}

// Update button text
function updateToggleText(theme) {
    const text = toggle.querySelector('.toggle-text');
    text.textContent = theme === 'dark' ? 'Light' : 'Dark';
    toggle.setAttribute('aria-label', `Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`);
}

// Initialize
updateToggleText(getTheme());

// Handle toggle click
toggle.addEventListener('click', () => {
    const current = getTheme();
    setTheme(current === 'dark' ? 'light' : 'dark');
});

// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
    if (!localStorage.getItem('theme')) {
        setTheme(e.matches ? 'dark' : 'light');
    }
});

Barrierefreiheit und Best Practices

Wesentliche Barrierefreiheits-Features

Ihr Dark-Mode-Umschalter muss per Tastatur zugänglich und korrekt beschriftet sein:

#theme-toggle:focus-visible {
    outline: 2px solid var(--accent-color);
    outline-offset: 2px;
}

Stellen Sie ausreichenden Farbkontrast in beiden Themes sicher. Dark Mode bedeutet nicht geringen Kontrast – halten Sie mindestens die WCAG-AA-Standards ein (4,5:1 für normalen Text).

Was Sie vermeiden sollten

Verwenden Sie nicht filter: invert(1) auf der gesamten Seite – dies invertiert unnötigerweise Bilder und Medien. Vermeiden Sie rein schwarze (#000000) Hintergründe im Dark Mode. Verwenden Sie dunkle Grautöne (#1a1a1a) für bessere Lesbarkeit. Verlassen Sie sich niemals ausschließlich auf JavaScript ohne CSS-Fallbacks.

Testen Ihrer Implementierung

Testen Sie Ihren Dark-Mode-Umschalter in verschiedenen Szenarien:

  1. Löschen Sie localStorage und überprüfen Sie, ob die Erkennung der Systemeinstellungen funktioniert
  2. Schalten Sie das Theme um und aktualisieren Sie die Seite, um die Persistenz zu bestätigen
  3. Ändern Sie die Systemeinstellungen, während die Website geöffnet ist
  4. Überprüfen Sie Kontrastverhältnisse mit den Browser-DevTools
  5. Testen Sie Tastaturnavigation und Screenreader-Ansagen

Fazit

Eine gut implementierte Dark-Mode-Lösung respektiert Benutzerpräferenzen, speichert Auswahl persistent und nutzt moderne CSS-Features. Durch die Kombination der color-scheme-Eigenschaft, Custom Properties und minimalem JavaScript erstellen Sie einen Theme-Switcher, der performant, barrierefrei und benutzerfreundlich ist. Die light-dark()-Funktion vereinfacht das Farbmanagement für moderne Browser, während Fallbacks die Kompatibilität sicherstellen.

Denken Sie daran: Die beste Dark-Mode-Implementierung ist für Benutzer unsichtbar – sie funktioniert einfach genau so, wie sie es erwarten.

FAQs

Ja, Sie können CSS Media Queries mit prefers-color-scheme verwenden, um Systemeinstellungen zu erkennen. JavaScript wird jedoch benötigt, um Benutzerpräferenzen zu speichern und einen manuellen Toggle-Button bereitzustellen, der Systemeinstellungen überschreibt.

Dies geschieht, wenn JavaScript nach dem Rendern der Seite ausgeführt wird. Platzieren Sie ein Script unmittelbar nach dem Body-Tag, das localStorage überprüft und das gespeicherte Theme anwendet, bevor die Seite gezeichnet wird, um dieses Aufblitzen zu verhindern.

Nein, reines Schwarz kann Augenbelastung verursachen und Text schwerer lesbar machen. Verwenden Sie stattdessen dunkle Grautöne wie #1a1a1a oder #121212. Diese Farben reduzieren die Belastung und bewahren gleichzeitig gute Kontrastverhältnisse für Barrierefreiheit.

Vermeiden Sie die Verwendung von filter invert auf Bildern. Stellen Sie stattdessen alternative Dark-Mode-Versionen von Bildern bereit oder verwenden Sie transparente PNGs mit Farben, die auf beiden Hintergründen funktionieren. Für komplexe Grafiken erwägen Sie die Verwendung von CSS-Masken oder SVGs mit currentColor.

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay