Introduction
Dark mode has gone from a nice-to-have feature to a user expectation. It enhances visual comfort in low-light environments, conserves battery life on OLED screens, and simply looks sleek. If your website or app doesn’t support a toggleable dark mode yet, you could be missing a key opportunity to improve user experience and accessibility.

In this guide, you’ll learn how to implement a toggleable dark mode using CSS and JavaScript, complete with localStorage persistence and system preference detection. Whether you’re updating a portfolio site or a large-scale web app, these best practices will help you add dark mode quickly, cleanly, and confidently.
1. Why Add Dark Mode?
Dark mode isn’t just about aesthetics—it adds real value to your user experience.
Benefits include:
- ✅ Reduces eye strain, especially at night
- ✅ Improves accessibility and visual focus
- ✅ Saves battery on OLED/AMOLED screens
- ✅ Aligns with OS-wide preferences for consistency
- ✅ Boosts user satisfaction and retention
Pro Insight: Apps like YouTube, Twitter, and GitHub have reported increased engagement after introducing dark mode.
2. Use CSS Custom Properties for Theme Flexibility
Rather than rewriting styles for dark mode, use CSS variables to define your color palette. This makes theme switching easy and maintainable.
Example: Base Theme Variables
cssCopyEdit:root {
--bg-color: #ffffff;
--text-color: #111111;
--accent-color: #0077cc;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
Dark Mode Theme
cssCopyEditbody.dark-mode {
--bg-color: #121212;
--text-color: #e4e4e4;
--accent-color: #4dabf7;
}
This setup allows you to apply the dark-mode
class to toggle all styles dynamically.
3. Add a Toggle Switch in HTML
Create a simple dark mode switch in your HTML layout.

htmlCopyEdit<label class="theme-toggle">
<input type="checkbox" id="darkToggle" />
Dark Mode
</label>
Style it to suit your design, or replace it with an icon-based toggle (🌞 / 🌙).
4. Enable Theme Switching with JavaScript
Now let’s add JavaScript to switch themes and store the preference.
JavaScript Code:
javascriptCopyEditconst toggle = document.getElementById('darkToggle');
const body = document.body;
// Load saved preference
if (localStorage.getItem('theme') === 'dark') {
body.classList.add('dark-mode');
toggle.checked = true;
}
// Toggle event
toggle.addEventListener('change', () => {
if (toggle.checked) {
body.classList.add('dark-mode');
localStorage.setItem('theme', 'dark');
} else {
body.classList.remove('dark-mode');
localStorage.setItem('theme', 'light');
}
});
Bonus: This ensures your theme stays consistent across page loads using localStorage
.
5. Detect System Theme Preferences Automatically
Respect the user’s OS-level preference using the prefers-color-scheme
media query.

CSS Detection:
cssCopyEdit@media (prefers-color-scheme: dark) {
:root {
--bg-color: #121212;
--text-color: #e4e4e4;
}
}
JavaScript Enhancement:
javascriptCopyEditif (!localStorage.getItem('theme')) {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
body.classList.add('dark-mode');
toggle.checked = true;
}
}
6. Style All Components for Both Themes
To provide a complete dark mode experience, style everything:
- Buttons, links, headers, and footers
- Forms, inputs, and modals
- Cards, tables, and navigation menus
Use transition effects to make the change smooth:
cssCopyEditbody {
transition: background-color 0.3s ease, color 0.3s ease;
}
7. Test for Accessibility and Usability
Checklist:
- ✅ High contrast ratios for readability
- ✅ Clear toggle placement
- ✅ Smooth transition effects
- ✅ Persistent theme on reload
- ✅ Compatibility with major browsers
Use tools like Lighthouse, axe DevTools, or Color Contrast Checker to audit your styles.
8. Dark Mode in Frameworks (Bonus Tips)
Using Tailwind CSS? You can enable dark mode via the dark
variant:

jsCopyEdit// tailwind.config.js
module.exports = {
darkMode: 'class', // or 'media'
}
Example:
htmlCopyEdit<div class="bg-white text-black dark:bg-gray-900 dark:text-white">
Content here...
</div>
Other frameworks like React, Vue, or Next.js can easily integrate this logic via global state or context providers.
Conclusion
Adding a toggleable dark mode is a small enhancement that delivers big results. With just a few lines of CSS and JavaScript, you can create a more accessible, modern, and user-friendly experience that aligns with how people want to use the web today.
At softwarehouse, we help developers and businesses implement accessible design features like dark mode for better engagement and inclusivity.
Ready to give your users more control over their experience? Start with the code above or reach out for custom implementation help.