
Dark Mode Toggle
Dark mode toggle without the flash of default theme. Important bits:
- CSS variables for color theming
- Put
data-theme
attribute on<html>
, not<body>
, so we can run the JS before the DOM finishes rendering - Run local storage check in the
<head>
- JS for toggle button click handler can come after render
HTML
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
...
<script>
// If there's a theme stored in localStorage, use it on the <html>
const localStorageTheme = localStorage.getItem('theme');
if (localStorageTheme) {
document.documentElement.setAttribute('data-theme', localStorageTheme);
}
</script>
</head>
<body>
<div class="theme-toggle">
<button
class="theme-toggle-btn js-theme-toggle"
aria-label="Activate dark mode"
title="Activate dark mode">
<!--
<svg class="light-mode">
<use xlink:href="#sun"></use>
</svg>
<svg class="dark-mode">
<use xlink:href="#moon"></use>
</svg>
-->
</button>
</div>
<script src="app.js"></script>
</body>
</html>
CSS Variables
:root {
--bg: #ffffff;
--text: #000000;
}
[data-theme='dark'] {
--bg: #000000;
--text: #ffffff;
}
JavaScript
app.js
const themeToggleBtn = document.querySelector('.js-theme-toggle');
themeToggleBtn.addEventListener('click', () => onToggleClick());
const onToggleClick = () => {
const { theme } = document.documentElement.dataset;
const themeTo = theme && theme === 'light' ? 'dark' : 'light';
const label = `Activate ${theme} mode`;
document.documentElement.setAttribute('data-theme', themeTo);
localStorage.setItem('theme', themeTo);
themeToggleBtn.setAttribute('aria-label', label);
themeToggleBtn.setAttribute('title', label);
};
Resources
About Dejan Georgiev
Hey! I'm Dejan, Founder of Uliasti, makers of Kaufpedia, Advanzo and Techify. Subscribe below to follow my thinking on business, faith, tech, product development, and whatever else is on my mind.
Thanks for visiting, thanks for reading.