CSS Light/Dark Mode ohne Duplizieren von Variablen – Implementation

Übersetzt und gekürzt von CSS Light/Dark Mode Implementation WITHOUT Duplicating Vars von Jane Ori

Inhaltsverzeichnis

Überblick

Viele denken, dass man für einen Light/Dark Mode in CSS alle --var-Deklarationen doppeln muss – für hell und dunkel. Doch: Das ist nicht nötig. Es geht auch eleganter.

Historischer Hintergrund

Ein Artikel von Bramus (Mai 2022) erklärte, dass eine Duplizierung notwendig sei. Doch dank neuer CSS-Features und seit Safari 16.4 (März 2023) ist das überflüssig – es funktioniert nun in allen modernen Browsern.

API / gewünschtes Verhalten

Diese Klassen ermöglichen flexible Steuerung des Farbschemas:

  • .theme-preferred – folgt der Systempräferenz
  • .theme-not-preferred – entgegengesetzt zur Präferenz
  • .theme-dark – erzwingt Dunkelmodus
  • .theme-light – erzwingt Hellmodus

Beispielhafte HTML-Struktur:

<div class="theme-dark">
    <span>dark</span>
    <div class="theme-light">light</div>
  </div>

Oder verschachtelt:

<main class="theme-preferred">
    <div class="theme-light">light</div>
    <div class="theme-dark">dark</div>
    <section class="theme-not-preferred">
      <div class="theme-preferred">preference</div>
      <div class="theme-light">light</div>
      <div class="theme-dark">dark</div>
    </section>
  </main>

Implementation (DRY-Ansatz)

Statt doppelte Variablen zu definieren, kombinieren wir Media Queries, CSS-Variablen und Space Toggles.

Grundstruktur / Boilerplate

Füge folgenden CSS-Code ein:

.theme-not-preferred,
  .theme-light {
    --media-prefers-light: ;
  }
  .theme-preferred,
  .theme-dark {
    --media-prefers-light: initial;
  }
  
  @media (prefers-color-scheme: light) {
    :root:not(.theme-dark):not(.theme-not-preferred),
    .theme-preferred {
      --media-prefers-light: ;
    }
    .theme-not-preferred {
      --media-prefers-light: initial;
    }
  }

Theme-Variablen definieren

Beispiel für drei Farben:

:root,
  .theme-preferred,
  .theme-not-preferred,
  .theme-light,
  .theme-dark {
    --theme_0_light: var(--media-prefers-light) 0 0% 100%;
    --theme_1_light: var(--media-prefers-light) 0 0% 0%;
    --theme_2_light: var(--media-prefers-light) hotpink;
    --theme_scheme: var(--media-prefers-light) light;
  
    --theme-0: var(--theme_0_light, 0 0% 0%);
    --theme-1: var(--theme_1_light, 0 0% 100%);
    --theme-2: var(--theme_2_light, rebeccapurple);
  
    color-scheme: var(--theme_scheme, dark);
  }

Erklärung:

  • --theme_x_light sind lichtspezifische Definitionen
  • --theme-x sind die tatsächlichen benutzten Werte
  • color-scheme passt native Elemente an

Verwendung im Layout

Beispielhafte Nutzung im CSS:

.my-info-box-component {
    background: hsl(var(--theme-0));
    color: hsl(var(--theme-1));
    border: 1px solid var(--theme-2);
    padding: 1rem;
  }

Und im HTML:

<aside class="my-info-box-component">
    Rand ist:
      - hotpink im Lightmode
      - rebeccapurple im Darkmode
  </aside>
  
  <aside class="my-info-box-component theme-not-preferred">
    Rand ist invertiert zur Präferenz
  </aside>
  
  <aside class="my-info-box-component theme-dark">
    Rand ist immer rebeccapurple
  </aside>

Demo

Ein Demo auf CodePen zeigt das System in Aktion: CodePen Beispiel

Mehr

Artikel auf css-tricks-com


Letzte Änderung am 12. Dezember 2025