In this darkmode code I allow the user to set the theme through system preferences while also allowing the user to override the system preferred theme by toggling the button or radio.
How do I set checked state for the system default radio when the user changes their system preference to auto?
Since it changes prefers-color-scheme to either light or dark how would I detect the user changing their preference to auto in order to update the radio's checked state? I tried adding the checked state inside of if (window.matchMedia("(prefers-color-scheme: no-preference)").matches) {} but it didn't execute.
Also I can't figure out why my window.addEventListener("load", (e) => {} isn't detecting the user selected theme on load. It's defaulting to light even when the page is refreshed and the theme in settings is set to dark.
https://codepen.io/moofawsaw/pen/VwmaPMV
$(document).ready(function() {
function setLight() {
$("body").removeClass("dark-theme");
$("body").addClass("light-theme");
$("#light").prop("checked", true);
$('input[name="theme"]').change();
}
function setDark() {
$("body").addClass("dark-theme");
$("body").removeClass("light-theme");
$("#dark").prop("checked", true);
$('input[name="theme"]').change();
}
function setMode() {
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
$("#dark").prop("checked", true);
$('input[name="theme"]').change();
setDark();
} else {
$("#light").prop("checked", true);
$('input[name="theme"]').change();
setLight();
}
}
//Check the mode on load and style accordingly
if (localStorage.getItem("mode") == "dark-theme") {
setDark();
} else {
setLight();
}
//Check for when system default is changed -> change theme
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
if (localStorage.getItem("mode") !== null) {
//Manually set so don't do anything
} else {
setMode();
}
});
window.addEventListener("load", (e) => {
//If the mode is mannually set on load - choose that mode
if (localStorage.getItem("mode") !== null) {
// Do nothing the mode has been set manually
} else {
// Set the mode to the default
setMode();
}
});
//add toggle
$("#toggleTheme").on("click", function() {
if ($("body").hasClass("dark-theme")) {
localStorage.setItem("mode", "light-theme");
setLight();
} else {
localStorage.setItem("mode", "dark-theme");
setDark();
}
});
$("#light").on("click", function() {
localStorage.setItem("mode", "light-theme");
setLight();
});
$("#dark").on("click", function() {
localStorage.setItem("mode", "dark-theme");
setDark();
});
$("#default").on("click", function() {
localStorage.removeItem("mode");
if (localStorage.getItem("mode") !== null) {
setMode();
}
});
});
//For selecting radio
$('input[name="theme"]').on("change", function() {
if ($(this).is(":checked")) {
$("label.checked").removeClass("checked");
$(this).closest("label").addClass("checked");
}
});
body {
--font-color: blue;
--bg-color: white;
--bg-span: #ececec;
}
body.dark-theme {
--font-color: white;
--bg-color: black;
--bg-span: white;
}
@media (prefers-color-scheme: dark) {
body {
--font-color: white;
--bg-color: black;
--bg-span: white;
}
body.light-theme {
--font-color: blue;
--bg-color: white;
--bg-span: #ececec;
}
}
body {
color: var(--font-color);
background: var(--bg-color);
}
button {
padding: 0.3rem 0.9rem;
outline: none;
color: var(--font-color);
background: var(--bg-color);
}
span {
padding: 0.9rem;
color: var(--font-color);
background: var(--bg-span);
}
img {
max-width: 190px;
}
/*input {
display: none;
}*/
label {
overflow: hidden;
display: flex;
flex-direction: column;
margin-right: 0.9rem;
border: 1px solid whitesmoke;
border-radius: 9px;
}
label.checked {
border: 3px solid blue;
}
.theme {
display: flex;
}
.buttons,
.theme {
padding: 1.3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="buttons">
<button id="toggleTheme">Mode</button>
</div>
<div class="theme">
<label for="light">
<img src="https://github.githubassets.com/images/modules/settings/color_mode_light.svg">
<input type="radio" name="theme" id="light">
<span>Light</span>
</label>
<label for="dark">
<img src="https://github.githubassets.com/images/modules/settings/color_mode_dark.svg">
<input type="radio" name="theme" id="dark">
<span>Dark</span>
</label>
<label for="default">
<img src="https://github.githubassets.com/images/modules/settings/color_mode_auto.svg">
<input type="radio" name="theme" id="default">
<span>System Default</span>
</label>
</div>