How to Add Dark Mode to Any Website in 5 Minutes

April 2026 ยท 5 min read ยท CSS

Dark mode isn't optional anymore โ€” it's expected. Users want it, and implementing it correctly is easier than you think. Here's a clean, CSS-first approach that works with any website.

Step 1: Define Your Color System with CSS Variables

The key to dark mode is CSS custom properties. Define all your colors in :root, then override them with a [data-theme="dark"] selector:

:root {
  --bg: #ffffff;
  --text: #1a1a2e;
  --text-secondary: #64748b;
  --card: #f8fafc;
  --border: #e2e8f0;
  --accent: #6366f1;
}

[data-theme="dark"] {
  --bg: #050507;
  --text: #f0f2f8;
  --text-secondary: #94a3b8;
  --card: #0a0b10;
  --border: rgba(255, 255, 255, 0.06);
  --accent: #818cf8;
}

Step 2: Use Variables Throughout Your CSS

Replace all hardcoded colors with your variables:

body {
  background: var(--bg);
  color: var(--text);
}

.card {
  background: var(--card);
  border: 1px solid var(--border);
}

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

Step 3: Add the Toggle Switch

<button id="themeToggle" aria-label="Toggle dark mode">
  ๐ŸŒ™
</button>

<script>
const toggle = document.getElementById('themeToggle');
const theme = localStorage.getItem('theme') || 
  (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');

document.documentElement.setAttribute('data-theme', theme);
toggle.textContent = theme === 'dark' ? 'โ˜€๏ธ' : '๐ŸŒ™';

toggle.addEventListener('click', () => {
  const current = document.documentElement.getAttribute('data-theme');
  const next = current === 'dark' ? 'light' : 'dark';
  document.documentElement.setAttribute('data-theme', next);
  localStorage.setItem('theme', next);
  toggle.textContent = next === 'dark' ? 'โ˜€๏ธ' : '๐ŸŒ™';
});
</script>
๐Ÿ’ก Pro tip: Always check localStorage first, then fall back to prefers-color-scheme. This respects both user preference and system settings.

Step 4: Respect System Preferences

For users who haven't explicitly toggled, auto-detect their OS preference:

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #050507;
    --text: #f0f2f8;
    /* ... dark values */
  }
}

Step 5: Smooth Transitions

body {
  transition: background-color 0.3s ease, color 0.3s ease;
}

Add this to prevent jarring color jumps when toggling.

Common Mistakes to Avoid

๐ŸŽจ 170+ dark mode templates, ready to ship

Every template in our bundle comes with dark mode built in. No configuration needed.

Get the Bundle โ€” $49

That's It

Five minutes, zero dependencies, works everywhere. CSS custom properties are the foundation of modern theming. Once you set up the variable system, you can add any number of themes โ€” not just dark and light.

Need more CSS tools? Check out our free developer tools โ€” gradient generators, shadow makers, and more.