<main>
<button>Toggle!</button>
<p>Current mode is: <output>system default</output></p>
<a href="https://codepen.io/chriskirknielsen/pen/YzpGKpq" target="_top">Vanilla CSS version →</a>
</main>
@function light-dark($light, $dark) {
// If light mode is --ON, we get the `initial` value thus the var() fallback is used, and the --OFF value is set to a whitespace, returning `$light `. Vice-versa for dark mode.
@return var(--light, #{ $light }) var(--dark, #{ $dark });
}
:root {
/* Thanks Lea Verou! https://lea.verou.me/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property/ */
--ON: initial;
--OFF: ;
}
.theme-default,
.theme-light {
--light: var(--ON);
--dark: var(--OFF);
}
.theme-dark {
--light: var(--OFF);
--dark: var(--ON);
}
@media (prefers-color-scheme: dark) {
.theme-default {
--light: var(--OFF);
--dark: var(--ON);
}
}
:root {
$light-link: navy;
$dark-link: gold;
/* Define each variable in their light and dark mode */
--text: #{ light-dark(black, white) };
--bg: #{ light-dark(orchid, rebeccapurple) };
--accent: #{ light-dark(mix(orchid, black), mix(rebeccapurple, white)) };
--link: #{ light-dark($light-link, $dark-link) };
}
body {
color: var(--text, black);
background: var(--bg, white);
}
/* Presentation */
body {
display: grid;
place-items: center;
min-height: 100vh;
}
main {
text-align: center;
}
button {
width: 100%;
}
p {
padding: 1em;
border: 0.5em solid var(--accent, #808080);
}
a:any-link {
color: var(--link, blue);
}
View Compiled
var darkMode = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
var toggle = function() {
document.querySelector('html').classList.remove('theme-default');
if (darkMode) {
document.querySelector('html').classList.add('theme-light');
document.querySelector('html').classList.remove('theme-dark');
}
else {
document.querySelector('html').classList.remove('theme-light');
document.querySelector('html').classList.add('theme-dark');
}
darkMode = !darkMode;
document.querySelector('output').innerText = darkMode ? 'dark' : 'light';
}
document.querySelector('button').addEventListener('click', toggle);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.