Because LESS variables resolve at compile time, building a runtime-switchable theme system requires either compiling multiple stylesheets or bridging LESS tokens into CSS custom properties. This lesson covers both approaches.
Two Approaches to Theming in LESS
The first approach compiles a separate CSS file per theme, each built from the same component styles but different token values, and swaps the linked stylesheet (or uses guarded mixins per theme). The second, more modern approach outputs LESS tokens as CSS custom properties, letting a single compiled stylesheet switch themes live in the browser.
The second approach is generally preferred today because it avoids duplicating compiled CSS and allows instant theme switching without a page reload or a second network request.
Compile LESS token values into CSS custom properties scoped under a data-theme attribute selector.
Toggle the theme at runtime with JavaScript by setting the data-theme attribute, no recompilation needed.
Component styles reference var(--custom-property), never the raw LESS @variable, so they stay theme-agnostic.
This pattern combines LESS's compile-time palette definition with native CSS's runtime flexibility.
LESS Theme System Cheatsheet
Key building blocks for a runtime-switchable theme system.
Building Block
Example
Purpose
Palette tokens
@color-bg-dark: #0f172a;
Raw theme-specific values, compile time
Custom property bridge
--color-bg: @color-bg-light;
Exposes a LESS value at runtime
Theme scope selector
[data-theme="dark"] { }
Overrides custom properties for a theme
Component usage
background: var(--color-bg);
Theme-agnostic component styles
Guarded mixin variant
.surface() when (@theme = dark) { }
Compile-time-only theme alternative
Compile-Time Theming with Guards
For projects that don't need live, in-browser theme switching, a simpler compile-time approach sets a single @theme variable and gates every relevant mixin with a guard, producing one fixed stylesheet per build.
Switching themes with this approach requires changing @theme and recompiling, no runtime switching.
Runtime Theming with Custom Properties
Bridging LESS tokens into CSS custom properties, scoped by a data-theme attribute or class, allows a single compiled CSS file to support instant, JavaScript-driven theme switching without recompilation.
The right approach depends on whether your product needs live theme switching (like a user-toggled dark mode) or a fixed theme decided at build time (like separate branded builds for different clients).
Use guarded compile-time theming for build-time brand variants with no runtime switching need.
Use the CSS custom property bridge for any user-facing light/dark or preference-based theme toggle.
The two approaches can also be combined: guards select a default theme, and custom properties allow runtime overrides.
Common Mistakes
Trying to switch a theme at runtime using only LESS @variables, which are already resolved into a static value at compile time.
Referencing a raw LESS @color-bg-dark variable directly in component styles instead of the theme-agnostic custom property.
Compiling a completely separate CSS bundle per theme when a lighter custom-property bridge would suffice.
Forgetting to define a sensible :root fallback for custom properties before any theme-specific override applies.
Key Takeaways
LESS variables resolve at compile time; true runtime theme switching requires bridging them into CSS custom properties.
A data-theme attribute selector combined with custom property overrides enables instant, JavaScript-driven theme switching.
Guarded, compile-time theming works well for fixed, build-time brand variants without live switching.
Component styles should reference custom properties, not raw LESS tokens, to stay theme-agnostic.
Pro Tip
Always author component styles against var(--token-name), never the raw @less-variable. This keeps every component automatically theme-aware without needing per-component theme logic.
You now know how to build a LESS-powered theme system. Next, apply BEM naming conventions on top of LESS's nesting features.