~/
Dark Mode & Theming
Quiz
...

Dark Mode & Theming

intermediate · updated Tue Sep 22 2026Contribute

Ship a dark theme and design tokens with CSS variables.

Dark Mode & Theming

Tailwind makes dark mode and theming straightforward with the dark: variant and CSS variables.

The dark: Variant

Add dark-specific styles alongside the light ones:

<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">
  <h1 class="text-gray-900 dark:text-white">Title</h1>
  <p class="text-gray-600 dark:text-gray-400">Body</p>
</div>

Every color utility has a dark counterpart. Pair them as you write.

Choosing the Dark Mode Strategy

Two common approaches:

  1. Media — Follow the operating system setting automatically.
  2. Class/selector — Toggle a class on <html> so users can choose.

Configure it in your CSS:

@custom-variant dark (&:where(.dark, .dark *));

Then toggling class="dark" on <html> switches the theme.

Toggling in JavaScript

const root = document.documentElement;
const stored = localStorage.getItem("theme");

if (stored === "dark" || (!stored && matchMedia("(prefers-color-scheme: dark)").matches)) {
  root.classList.add("dark");
}

function toggleTheme() {
  root.classList.toggle("dark");
  localStorage.setItem("theme", root.classList.contains("dark") ? "dark" : "light");
}

Persist the choice so it survives reloads.

Design Tokens with CSS Variables

Define semantic colors once, then reference them:

@import "tailwindcss";

@theme {
  --color-background: oklch(1 0 0);
  --color-foreground: oklch(0.2 0 0);
}

.dark {
  --color-background: oklch(0.15 0 0);
  --color-foreground: oklch(0.95 0 0);
}

Now bg-background and text-foreground automatically flip with the theme. Semantic names beat hardcoded gray-900 scattered everywhere.

Best Practices

  1. Use semantic tokensbg-background, not bg-gray-100.
  2. Check contrast in both themes — Dark mode is not just inverted colors.
  3. Respect system preference by default.
  4. Persist the user’s choice.

Common Mistakes

  1. Only styling light mode — Dark users get white flashes.
  2. Hardcoding colors everywhere — Theming becomes a find-and-replace.
  3. Forgetting images and shadows — They often need dark adjustments.
  4. Low contrast — Pure black on pure white is harsh; use near-black/near-white.