1 min read
Dark mode without the flash
The no-FOUC pattern: resolve the theme in a blocking script before first paint.
- #css
- #javascript
- #theming
The flash of the wrong theme happens when the page paints before your theme logic runs. The fix is a tiny render-blocking script in <head>, before any stylesheet.
The script
(() => {
let theme;
try {
theme = localStorage.getItem('theme');
} catch {}
const dark =
theme === 'dark' ||
(theme !== 'light' && matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList.toggle('dark', dark);
})();
Why it works
Inline scripts block parsing, so the .dark class lands on <html> before the body ever renders. Explicit user choice wins; otherwise the OS preference decides.