Adding Interactivity with JavaScriptLesson 3.2
How to implement dark mode toggle in a portfolio
dark mode, CSS custom properties, data-theme attribute, localStorage, prefers-color-scheme, classList toggle, system preference detection
Dark Mode Without a Framework
Dark mode is implemented at the CSS layer using custom properties and a data-theme attribute on the html element. JavaScript only toggles that attribute and persists the preference.
CSS: Two Theme Definitions
:root {
--bg: #ffffff;
--text: #111827;
--border: #e5e7eb;
}
[data-theme="dark"] {
--bg: #0f172a;
--text: #f1f5f9;
--border: #334155;
}
body {
background-color: var(--bg);
color: var(--text);
transition: background-color 0.2s ease, color 0.2s ease;
}JavaScript: Toggle and Persist
const toggle = document.querySelector('#theme-toggle');
const root = document.documentElement;
// Respect system preference on first load
if (localStorage.getItem('theme') === 'dark' ||
(!localStorage.getItem('theme') &&
window.matchMedia('(prefers-color-scheme: dark)').matches)) {
root.setAttribute('data-theme', 'dark');
}
toggle.addEventListener('click', () => {
const isDark = root.getAttribute('data-theme') === 'dark';
root.setAttribute('data-theme', isDark ? 'light' : 'dark');
localStorage.setItem('theme', isDark ? 'light' : 'dark');
});Check localStorage first, then fall back to prefers-color-scheme. This means first-time visitors get their system preference automatically, and returning visitors get their manual choice. Add the toggle button to your nav with a sun/moon icon or simple text label.
