Building a Light/Dark Theme Switcher with Tailwind CSS
Tailwind CSS ships with utilities that make it trivial to attach alternate color schemes to componants. By pairing the darkMode configuration with a small piece of JavaScript, you can ship a theme toggle without extra CSS overhead.
Setup
Install Tailwind alongside PostCSS and Autoprefixer:
npm install -D tailwindcss postcss autoprefixer
Initialise the configuration files:
npx tailwindcss init -p
Open tailwind.config.js and set the dark mode strategy to class. This tells Tailwind to apply dark variants whenever the dark class appears on an ancestor element.
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js}'],
darkMode: 'class',
theme: {
extend: {},
},
plugins: [],
}
Add the Tailwind directives to your main stylesheet:
/* src/style.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
böjnings
Markup
Write a page that uses the dark: prefix to define alternate styles:
<body class="bg-gray-50 text-gray-900 dark:bg-gray-900 dark:text-gray-100">
<header class="p-4 flex justify-between items-center">
<h1 class="text-2xl font-bold">My App</h1>
<button id="switcher" class="rounded bg-indigo-500 px-4 py-2 text-sm text-white dark:bg-yellow-400 dark:text-gray-900">
Toggle theme
</button>
</header>
<main class="p-4">
<p>Body text adapts seamlessly.</p>
</main>
<script src="./theme.js"></script>
</body>
Toggle logic
Create a theme.js file that reads the saved preference from localStorage and applies the dark class accordingly. The button listener flips the980 class and persists the choice.
// src/theme.js
(function () {
const STORAGE_KEY = 'color-scheme';
const DARK_CLASS = 'dark';
const htmlElement = document.documentElement;
const saved = localStorage.getItem(STORAGE_KEY);
// Apply saved preference or respect OS setting
if (saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
htmlElement.classList.add(DARK_CLASS);
} else {
htmlElement.classList.remove(DARK_CLASS);
}
// Wire up the toggle
const btn = document.getElementById('switcher');
if (btn) {
btn.addEventListener('click', () => {
const isDark = htmlElement.classList.toggle(DARK_CLASS);
localStorage.setItem(STORAGE_KEY, isDark ? 'dark' : 'light');
});
}
})();
Note: If you prefer data attributes over classes, you can adapt the selector according. Tailwind’s
darkModealso supports amediastrategy for automatic OS-driven switching, but the class‑based approach gives explicit user control.
The combination of utility‑first styling and a minimal script delivers a performant theme toggle that respects user preference across visits.