Light/Dark Support for WordPress and Bootstrap 5
Light and dark mode support is no longer a novelty feature. It is a user preference, an accessibility concern, and an expected part of modern interface design.
Boilerplate treats color mode as a first-class theme system instead of a one-off visual toggle. The goal is simple: respect the user’s operating system preference by default, allow an intentional override when they want one, and make the entire WordPress theme respond cleanly through CSS custom properties, Bootstrap 5 theme attributes, and predictable root classes.
Why light/dark support matters
Dark mode adoption is widespread enough that ignoring it means ignoring how a meaningful percentage of users already browse, read, and work. Third-party dark mode statistics from forms.app and EarthWeb both point to strong dark mode usage, especially on mobile devices. The exact numbers vary depending on the audience and methodology, but the direction is obvious: users expect interfaces to adapt.
For Boilerplate, this is not just about aesthetics. Accessibility is a major part of the decision.
Respect the system first
The default behavior starts with the operating system. If the visitor has a light or dark preference set at the OS/browser level, Boilerplate can follow that automatically through prefers-color-scheme. This matters because the best toggle is often no toggle at all. When a user has already told their device how they prefer interfaces to look, the website should listen.
The JavaScript layer in assets/js/color_mode.js resolves the active mode, watches for system preference changes, and applies the correct state to the document root. That gives the theme a single reliable place to determine whether the rendered interface should behave as light or dark.
Allow the user to override it
Boilerplate allows the visitor to override the resolved mode. When a user clicks the color mode toggle, their choice is stored in localStorage, so future page views continue using the selected mode instead of resetting on every request.
This gives the theme a practical hierarchy:
- Use the configured default mode
- Resolve
systemmode throughprefers-color-scheme - Respect the user’s saved light/dark override when one exists
- Update the interface immediately when the toggle is used
The result feels simple to the visitor, but it avoids the common problem where a dark mode toggle only changes part of the page or forgets the user’s preference on the next load.
Bootstrap 5 needs to know too
Because Boilerplate is built on Bootstrap 5, color mode cannot only exist in custom theme classes. Bootstrap needs to receive the resolved mode as well.
Boilerplate handles that by setting Bootstrap’s data-bs-theme attribute on the root element. When the resolved mode is dark, Bootstrap receives data-bs-theme="dark". When the resolved mode is light, it receives data-bs-theme="light".
That keeps Bootstrap components and Boilerplate theme components moving in the same direction. Forms, dropdowns, navbars, buttons, borders, and other shared UI elements can all participate in the same color mode system instead of fighting each other.
Root classes make the state obvious
Boilerplate also applies explicit root classes such as bp_theme_light, bp_theme_dark, bp_theme_system, bp_theme_resolved_light, and bp_theme_resolved_dark.
That distinction is useful. The selected mode and the resolved mode are not always the same thing. A user may be in system mode, but the resolved output may currently be dark because their OS is set to dark. Tracking both states makes the system easier to debug, easier to style, and easier to extend.
CSS custom properties do the heavy lifting
The real power of Boilerplate’s color mode system lives in SASS and CSS custom properties.
Theme defaults are organized in assets/sass/parent_theme/variables.scss. Runtime light and dark values are emitted through assets/sass/parent_theme/color_mode.scss. Instead of hardcoding colors across every component, the theme routes colors through custom properties like body colors, border colors, link colors, button colors, input colors, navbar colors, widget colors, comment colors, media colors, and more.
That gives the theme one consistent color language. Components do not need to know whether the site is currently light or dark. They only need to use the correct token.
Menu-link toggles keep it WordPress-native
Color mode controls are also designed to be placed through the WordPress menu editor. Instead of hardcoding a toggle into the navbar template, Boilerplate supports special Custom Link URLs that render as theme controls.
#bp-color-mode-toggle#bp-color-mode-toggle-with-text
4/15/2026 - jmparks