This page explains how to add a "dark mode" to your web page, with the following nice properties:
Try it on this page! (And then, try refreshing.)
This button should reset the theme to your system preference:
We'll use a .dark class on the <html> tag to control dark mode. The CSS looks like this:
/* The light and dark theme color variables are defined up here: */ html, html.light { color-scheme: light; --text: #111; --accent: #f80; --bg: #eef; } html.dark { color-scheme: dark; --text: #dde; --accent: #ec0; --bg: #334; } /* It sucks a little to have to define the dark colors twice, */ /* but this makes it work even when JavaScript is disabled: */ @media (prefers-color-scheme: dark) { html { color-scheme: dark; --text: #dde; --accent: #ec0; --bg: #334; } } /* The rest of your page style goes below here. */ body { transition: background-color 0.2s; background-color: var(--bg); color: var(--text); /* et cetera */ }
Put this code in a script tag above the body (at the end of <head>), to prevent a flash of the incorrect theme when the page first loads.
<script>
function lget(key) { try { return localStorage.getItem(key); } catch (e) { return null; } }
function lset(key, value) { try { localStorage.setItem(key, value); } catch (e) {} }
function prefersDark() { return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; }
function getTheme() { return lget("theme") || (prefersDark() ? "dark" : "light"); }
function setTheme(theme) { lset("theme", theme); document.querySelector("html").className = theme || getTheme(); }
function toggleTheme() { setTheme(getTheme() === "dark" ? "light" : "dark"); }
setTheme(getTheme());
</script>
Finally, put a button like this somewhere on your page, and you're done!
<button onclick="toggleTheme()">Toggle theme</button>
You can also call setTheme('light') or setTheme('dark') or setTheme('') (follow system preference).
Here's a fancier emoji-based toggle: View this page's source code to see how it works!