← Main site

How It Works

Tabule Theme's dark mode is a full alternative color scheme that visitors can toggle on demand. It is designed to load instantly — without any flash of the wrong color — and to remember the visitor's preference between page loads and browser sessions.

The anti-FOUC script

The most important part of the dark mode implementation is an inline <script> injected into <head> at the very highest priority (before any CSS loads). This script runs synchronously, which means it completes before the browser paints anything.

What the script does:

  1. Reads localStorage.getItem("tbl-color-scheme") to check if the visitor has a saved preference.
  2. If a preference exists, it sets document.documentElement.setAttribute("data-theme", "dark" | "light") immediately.
  3. If no preference exists, it falls back to the Default Mode setting configured in the Customizer — either a fixed light or dark, or the system's prefers-color-scheme media query.

Because this runs before CSS, the page renders in the correct theme on the very first paint. Visitors never see a white flash before dark mode activates.

CSS architecture

Dark mode styles live in a separate dark-mode.css file that is only enqueued when dark mode is enabled in the Customizer. It uses the [data-theme="dark"] attribute selector on the <html> element to override all relevant CSS custom properties and colors.

Toggle button

When the toggle button is enabled, dark-mode.js is loaded with the defer attribute. The script handles click events on the toggle button. When clicked, it:

  1. Flips the data-theme attribute on <html>.
  2. Saves the new preference to localStorage as tbl-color-scheme.

Priority of preference resolution

  1. Visitor's saved preference in localStorage (from a previous manual toggle) — highest priority.
  2. Customizer Default Mode: Always Dark or Always Light.
  3. Customizer Default Mode: Follow system preference — uses the browser's prefers-color-scheme: dark media query.

No cookies, no server-side logic

The preference is stored entirely in localStorage. No cookies are set and no server-side state is involved. This means the dark mode choice does not affect caching and does not require any consent banner entry for GDPR purposes.