Skip to content

Accessible Theme Switcher

A theme toggle that respects system preferences and persists user choice.

JavaScript CSS localStorage
April 2024

Features

  • Respects prefers-color-scheme media query
  • Persists user preference in localStorage
  • No flash of wrong theme on load
  • Smooth transitions between themes

Implementation

The key is to run the theme detection script before the page renders.

Inline Script in Head

<script>
  const theme = (() => {
    const stored = localStorage.getItem('theme');
    if (stored === 'dark' || stored === 'light') return stored;
    return window.matchMedia('(prefers-color-scheme: dark)').matches
      ? 'dark'
      : 'light';
  })();
  document.documentElement.classList.toggle('dark', theme === 'dark');
</script>

Toggle Function

function toggleTheme() {
  const html = document.documentElement;
  html.classList.toggle('dark');
  const theme = html.classList.contains('dark') ? 'dark' : 'light';
  localStorage.setItem('theme', theme);
}

CSS Variables for Themes

:root {
  --bg-color: #ffffff;
  --text-color: #1a1a1a;
}

.dark {
  --bg-color: #1a1a1a;
  --text-color: #ffffff;
}