Building a Dark Mode Toggle with Tailwind CSS

Adding a dark mode toggle to your site is a quick way to improve user experience and make your UI look modern. Tailwind CSS makes it surprisingly simple to implement with minimal JavaScript.
How Tailwind Handles Dark Mode
Tailwind uses a class-based approach for dark mode. By default, it looks for a class="dark"
on the root <html>
or <body>
tag. Once present, it applies dark-specific utility classes like dark:bg-gray-900
or dark:text-white
.
This gives you full control over when and how dark mode is enabled, instead of relying on media queries alone.
Enable Dark Mode in Tailwind Config
Open your tailwind.config.js
file and make sure darkMode
is set to 'class'
:
module.exports = {
darkMode: 'class',
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
}
Creating the Toggle Logic
You can store the theme preference in localStorage
so it persists between visits. Here’s a simple script to handle toggling:
function toggleDarkMode() {
const html = document.documentElement
const isDark = html.classList.toggle('dark')
localStorage.setItem('theme', isDark ? 'dark' : 'light')
}
// Optional: load theme on page load
const savedTheme = localStorage.getItem('theme')
if (savedTheme === 'dark') {
document.documentElement.classList.add('dark')
}
Adding the Toggle Button
Here’s a basic toggle button you can place in your header or navbar:
<button onclick="toggleDarkMode()" class="p-2 border rounded">
Toggle Dark Mode
</button>
You can customize this with icons, transitions, or state awareness if needed. For example, you could use a sun/moon SVG instead of text.
Using Dark Classes in Tailwind
Tailwind lets you define alternate styles using the dark:
prefix. Here are a few examples:
<div class="bg-white text-black dark:bg-gray-900 dark:text-white">
This box adapts to the current theme.
</div>
Almost every Tailwind utility supports the dark:
prefix, so you can fully theme your site without extra CSS.
Optional: Sync with System Preference
If you want the site to default to the user’s system preference, you can add this check before anything else runs:
if (
localStorage.getItem('theme') === 'dark' ||
(!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark')
}
This way, your site feels natural to users whether they use light or dark mode by default.