short js snippet for dark mode, that listens to a button and to the theme change of the browser
- save preferred theme in localstorage until preferred theme and browser theme maches
- changes theme at page load
- short and efficient, without css classes or custom styles
- works with all modern browsers:
- ✅ Chromium [Chrome, Brave, Edge, Opera]
- ✅ Firefox
- ✅ Safari [Epiphany]
- add button
<button type="button">toggle dark mode</button>
- add
[data-theme="dark"]
entry to the css stylesheet
you can change variables from :root
...
:root {
--background: white;
}
[data-theme="dark"] {
--background: dark
}
...or change other entries directly
.someClass {
color: black
}
[data-theme="dark"] .someClass {
color: white
}
- add js code
// button listener
document.querySelector('[YOUR_BUTTON]').addEventListener("click", () => changeScheme('button'));
// OS listener
const schemeChange = e => e.matches && changeScheme('browser');
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", schemeChange);
window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", schemeChange);
// return systemScheme unless localStorage is set;
function getPreferred() {
const systemScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
const chosenScheme = localStorage.getItem("scheme") || systemScheme;
if (systemScheme === chosenScheme) localStorage.removeItem("scheme");
return [chosenScheme, systemScheme];
}
// change system scheme and set localStorage
function changeScheme(reason) {
if (reason == "browser" && scheme == getPreferred()[1]) return;
scheme = (scheme === 'dark') ? 'light' : 'dark';
if (reason == "button") localStorage.setItem("scheme", scheme);
document.documentElement.setAttribute('data-theme', scheme);
}
// if needed, change scheme on start
window.onload = () => {
scheme = getPreferred()[0];
document.documentElement.setAttribute('data-theme', scheme);
}