ui tailwindcss

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");
  }
}