Home / Snippets / Layout /

Multi-brand tokens

A CSS custom property architecture for multi-brand design systems. Switch themes with a single data attribute.

Alpha brand

Purple accent with medium rounding for a modern SaaS feel.

Beta brand

Green accent with pill-shaped buttons for a health-tech vibe.

Gamma brand

Warm orange accent with sharp corners for an editorial look.

Widely Supported
layoutno-js

Quick implementation

/* --- Brand token layers --- */
[data-brand="alpha"] {
  --brand-accent: oklch(0.72 0.19 265);
  --brand-surface: oklch(0.22 0.03 265);
  --brand-radius: 0.5rem;
}

[data-brand="beta"] {
  --brand-accent: oklch(0.70 0.18 155);
  --brand-surface: oklch(0.22 0.03 155);
  --brand-radius: 1rem;
}

[data-brand="gamma"] {
  --brand-accent: oklch(0.72 0.20 25);
  --brand-surface: oklch(0.22 0.03 25);
  --brand-radius: 0.25rem;
}

/* --- Components consume tokens --- */
.card {
  padding: 1.25rem;
  border-radius: var(--brand-radius);
  background: var(--brand-surface);
}

.card-title {
  color: var(--brand-accent);
}

.btn-brand {
  padding: 0.4rem 1rem;
  border: none;
  border-radius: var(--brand-radius);
  background: var(--brand-accent);
  color: oklch(0.98 0 0);
  font-weight: 600;
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer building a multi-brand design system.

Goal: A CSS custom property architecture that lets you switch an entire
brand theme by toggling a single data attribute — no JavaScript reloads.

Technical constraints:
- Define brand tokens under [data-brand="name"] attribute selectors.
- Each brand must set at minimum: --brand-accent, --brand-surface,
  --brand-radius, and --brand-text.
- All color values must use oklch() — no hex, rgb, or hsl.
- Components (cards, buttons, headings) reference only token variables,
  never hard-coded colors.
- Custom properties must inherit through the DOM tree so nested
  components pick up the correct brand automatically.

Framework variant (pick one):
A) Vanilla CSS with data-attribute selectors on a wrapper element.
B) React component — accept a "brand" prop that sets the data attribute
   on a wrapper div, with children consuming tokens via CSS.

Edge cases to handle:
- Provide a sensible fallback when no data-brand is set.
- Ensure tokens compose with site-level dark-mode variables.
- Support nesting one brand inside another without token leakage.

Return CSS.

Why this matters in 2026

White-label products and multi-tenant SaaS platforms are everywhere. Instead of shipping separate stylesheets per brand, a single token layer with [data-brand] attribute selectors lets you switch the entire visual identity at the DOM level. This pattern scales from two brands to twenty without build-step complexity or runtime JavaScript.

The logic

Each [data-brand] selector defines a set of custom properties — accent color, surface color, border-radius, and more. Components never reference hard-coded values; they consume var(--brand-accent) and var(--brand-surface) instead. Because CSS custom properties inherit down the DOM tree, wrapping any subtree in a data-brand container automatically re-themes every nested component. The attribute selector has just enough specificity to override defaults without fighting !important rules.

Accessibility & performance

This pattern has zero runtime cost — there is no JavaScript, no class toggling, and no style recalculation beyond the initial cascade. Switching brands is a single attribute change that the browser resolves in one style pass. For accessibility, ensure each brand palette meets WCAG contrast ratios; oklch() makes this straightforward because lightness is the first channel, so you can verify contrast by comparing L values directly.