Theming
Supporting several visual identities from one system, which is a token architecture problem before it is a design problem.
Definition
Theming remaps the semantic token layer to produce a different visual identity from the same components. Common cases are light and dark modes, high contrast, and multi-brand or white-label products.
Craft convention. True because the industry converged on it. Breaking it costs familiarity, not correctness.
On this plate
Reach for this when
- Adding dark mode.
- Supporting multiple brands.
- Building a white-label product.
Common mistakes
- Theming implemented per component rather than through tokens.
- Contrast verified in one theme only.
- Unbounded customer colour input.
- Too many themeable dimensions to test.
Decisions to make early
- What varies: colour only, or also type, spacing, radius and density? Each addition multiplies the testing surface.
- Where the boundary is: which tokens are themeable and which are fixed.
- How themes are delivered: CSS custom properties, build-time generation, or runtime switching.
- How contrast is verified per theme, since a compliant light theme says nothing about the dark one.
- Whether customers can supply their own colours, which requires automatic contrast correction rather than trust.
Delivery mechanisms
| Mechanism | Switch cost | Use when |
|---|---|---|
| Custom properties on a root attribute | Instant, no reload | Light and dark, or a small fixed set of brands. |
| A stylesheet per theme | One network request | Themes are large and switched rarely. |
| Build-time generation, one bundle per brand | A deploy | White-label products with one brand per deployment. |
| Runtime values fetched per tenant | One request at boot | Customer-supplied colours resolved at sign-in. |
| Component props | None, and none of the benefit either | Never, as a system strategy. This is the situation tokens exist to remove. |
A theme is a remap, not a stylesheet
/* Semantic layer: the only thing a theme touches. */
:root {
--surface-page: var(--grey-050);
--text-primary: var(--grey-900);
--action-primary: var(--blue-600);
}
[data-theme="dark"] {
--surface-page: var(--grey-900);
--text-primary: var(--grey-050);
--action-primary: var(--blue-300); /* lighter, to hold contrast on dark */
}
[data-theme="contrast"] {
--surface-page: #000;
--text-primary: #fff;
--action-primary: #ffd400;
}
.card {
background: var(--surface-page);
color: var(--text-primary);
}Three themes, no component changes. If a theme needs a rule inside a component, the token boundary is in the wrong place.
Practical rules
Do
- Check contrast per theme automatically, against the generated values rather than the design intent.
- Derive the dark palette from intent. Inverting lightness usually fails both contrast and brand recognition.
- Keep one themeable dimension unless a second is genuinely required. Colour plus density is already four times the visual testing.
- Give each theme the name the business uses, so support conversations and code refer to the same thing.
Do not
- Do not ship a theme without checking focus indicators in it. They are the first thing to disappear on dark and high-contrast surfaces.
- Do not let a component read the active theme. A component that branches on theme cannot be themed by anyone else.
- Do not treat high contrast as a darker dark mode. It is a separate requirement with its own ratios.
- Do not accept a customer hex value as a fill without correcting it. Derive a compliant ramp and show what changed.
Local chart
SYS·008 · Region VI · Grid C3
This entry and the entries it is stated to connect with. Each line is labelled with what the connection means.
Continue from here
Each link says what the connection is, so you can tell a principle from an alternative from a thing people mix this up with.
Depends on
Get these right first, or this one will not hold.
- Design TokensSYS·001 · Design system
Theming is token remapping. Without a semantic token layer there is nothing to remap.
Often used with
These usually appear in the same screen or the same decision.
- Style DictionaryTOOL·040 · Tool
- SupernovaTOOL·039 · Tool
Related concept
Connected closely enough to change how you apply this.
- Component API DesignSYS·002 · Design system
- Brand Color in InterfacesFND·024 · UI foundation
- Color AccessibilityFND·028 · UI foundation
- Color SystemsFND·026 · UI foundation
- ContrastFND·002 · UI foundation
- Dark ModeFND·027 · UI foundation