Darkmode mit CSS-Variablen

Warum Darkmode? Viele Menschen empfinden helle Webseiten abends oder bei wenig Umgebungslicht als anstrengend für die Augen. Ein Darkmode schont die Augen, spart auf OLED-Displays Energie und sorgt für bessere Zugänglichkeit. Mit CSS-Variablen und wenig JavaScript kannst du deiner Seite einen Umschalter für den Dunkelmodus geben – unabhängig von den Systemeinstellungen.

Darkmode mit CSS-Variablen und Button

  1. CSS-Variablen für Farben anlegen: Definiere im :root Standardfarben für Hintergrund und Text.

    :root {
      --bg: #fff;
      --text: #222;
    }
    
    body {
      background: var(--bg);
      color: var(--text);
    }

    CSS

  2. Darkmode mit Media Query als Standard aktivieren: Nutze die Systemeinstellung nur dann, wenn noch kein Theme per Button gesetzt wurde.

    @media (prefers-color-scheme: dark) {
      html:not([data-theme]) {
        --bg: #181c1f;
        --text: #f3f3f3;
      }
    }

    CSS

  3. Button zum Umschalten ergänzen: Mit einem Button kannst du unabhängig vom System zwischen Hell und Dunkel wechseln. Füge einen Button ins HTML ein:

    <button id="darkmode-toggle" type="button">Darkmode umschalten</button>

    HTML

  4. Theme explizit per Attribut setzen: Mit einem Attribut auf html überschreibst du die Media Query in beide Richtungen.

    html[data-theme="dark"] {
      --bg: #181c1f;
      --text: #f3f3f3;
    }
    
    html[data-theme="light"] {
      --bg: #fff;
      --text: #222;
    }

    CSS

  5. JavaScript zum Umschalten: Dieses Skript toggelt zwischen light und dark, speichert die Auswahl und funktioniert unabhängig von der Media Query.

    const darkmodeButton = document.getElementById('darkmode-toggle');
    const root = document.documentElement;
    const storageKey = 'theme';
    
    if (!darkmodeButton) {
      return;
    }
    
    const gespeichertesTheme = localStorage.getItem(storageKey);
    if (gespeichertesTheme === 'light' || gespeichertesTheme === 'dark') {
      root.setAttribute('data-theme', gespeichertesTheme);
    }
    
    darkmodeButton.addEventListener('click', function () {
      const aktuellesTheme = root.getAttribute('data-theme')
        || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
      const naechstesTheme = aktuellesTheme === 'dark' ? 'light' : 'dark';
    
      root.setAttribute('data-theme', naechstesTheme);
      localStorage.setItem(storageKey, naechstesTheme);
    });

    JS