Dark Mode — The CSS Custom Properties Approach
The correct way to implement dark mode uses CSS custom properties (variables) for all colors. Define the light palette on :root, redefine only the color tokens under prefers-color-scheme: dark. All components use the variables — switching the theme requires no per-component changes.
/* Light theme (default) */
:root {
--bg: #ffffff;
--text: #1a1a2e;
--card: #f8f9fa;
--border: rgba(0,0,0,.1);
}
/* Dark theme — OS preference */
@media (prefers-color-scheme: dark) {
:root {
--bg: #06080f;
--text: #f1f5f9;
--card: #0d1117;
--border: rgba(255,255,255,.07);
}
}
/* Manual toggle override */
[data-theme="light"] {
--bg: #ffffff;
--text: #1a1a2e;
}
Dark Mode Toggle — JavaScript (15 Lines)
// Read saved preference or detect OS
const saved = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme:dark)').matches;
const theme = saved || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
// Toggle button click handler
document.getElementById('theme-toggle').addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});
Frequently Asked Questions
How do I add dark mode to an HTML website?
Define all colors as CSS custom properties on :root. Add a @media (prefers-color-scheme: dark) block that redefines only the color tokens. For a manual toggle, add data-theme attribute handling: a JavaScript click handler sets data-theme on the html element and saves to localStorage. Total code: about 15 lines.
What is the best background color for dark mode?
Avoid pure black (#000000) — it causes halation on OLED screens where bright text bleeds into the pure-black background. Use a very dark near-black: #06080f, #0d1117, or #111827. For text, use near-white instead of pure white: #f1f5f9 or rgba(255,255,255,.87) reduces eye strain in dark environments.
How do I save the dark mode preference in a browser?
Use localStorage: localStorage.setItem('theme', 'dark') to save and localStorage.getItem('theme') to read on page load. Also check window.matchMedia('(prefers-color-scheme: dark)').matches as the default when no preference is saved. This ensures the OS preference is respected on first visit.
Should I default to dark or light mode?
Default to the user's OS preference using prefers-color-scheme. Users who set their OS to dark mode expect websites to respect that preference. Defaulting to light and forcing users to toggle is a UX friction point. Read the OS preference, apply it immediately, then allow manual override.
Do UIXDraft HTML templates support dark mode?
Yes. All UIXDraft templates are built with CSS custom properties (--bg, --card, --t1, --t2, --border) — the exact architecture needed for dark mode. Switch the color tokens in a @media block to implement dark/light mode instantly. One $35 purchase, 180+ templates.