Toggle light/dark here, elsewhere
Marcelino Veloso III,TailwindCSS Configuration
A common formula for switching themes involves the <html>
tag. At least, this is the practice employed by TailwindCSS and PicoCSS. tailwind.config.js
contains a top-level configuration instructing that dark mode can be enabled through the class attribute:
module.exports = {
darkMode: "class",
// other settings
};
HTML Attribute and LocalStorage
To make it easier to reference the <html>
tag's class=
attribute, I use baseKlass
:
const baseKlass = document.documentElement.classList;
Every time I want to change this tag, I simply supply the value of either light or dark to the function below:
function setTheme(val) {
baseKlass.add(val);
localStorage.setItem("theme", val); //
}
With setup out of the way, can proceed to initializing and toggling.
Initialization of the Theme
With respect to initialization, even before the <html>
element is loaded on the page, javascript ensures this loads as <html class='dark'>
or <html class='light'>
depending on either the presence of an existing value in the browser's Local Storage or a user browser preference. This is the import of the initializing function:
function themeHTML() {
if (localStorage.getItem("theme") === "dark") {
baseKlass.add("dark");
} else if (localStorage.getItem("theme") === "light") {
baseKlass.add("light");
} else if (window.matchMedia("(prefers-color-scheme: dark)")) {
setTheme("dark");
} else {
setTheme("light");
}
}
We use his function only once: when the site loads for the first time.
<!DOCTYPE html>
<script src="doTheme.js"></script>
<script>themeHTML()</script>
<html><!-- body, etc. --></html>
The ordering of the script matters to prevent flickering from light to dark.
Toggling the Theme
Somewhere within the body of the <html>
tag, we should be able to provide a toggle button.
When this button is clicked, the toggling function setTheme()
gets called to change the existing setting.
function toggleTheme() {
if (baseKlass.contains("dark")) {
baseKlass.remove("dark");
setTheme("light");
} else if (baseKlass.contains("light")) {
baseKlass.remove("light");
setTheme("dark");
}
}