<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 &rarr;</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);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.