Design System Problems

Contextual Design Tokens

January 15, 2026 • 5 min read

Contextual Design Tokens

Contextual design tokens adapt their values based on the context in which they are used. Unlike static tokens that resolve to fixed values, contextual tokens respond to their environment: the container they appear in, the viewport size, user preferences, or other runtime conditions. This adaptability enables more sophisticated design systems that respond to diverse usage scenarios.

What Are Contextual Design Tokens

Contextual design tokens are tokens whose resolved values depend on contextual factors. The same token name might resolve to different values based on viewport width, container dimensions, color scheme preference, user accessibility settings, or other environmental conditions.

Context-awareness enables tokens to carry adaptive behavior rather than requiring component code to handle all contextual variations explicitly.

How Contextual Design Tokens Work

Context can influence tokens in several ways.

Theme context switches token values based on active theme:

:root {
  --color-surface: #ffffff;
}

[data-theme="dark"] {
  --color-surface: #1a1a1a;
}

Components use --color-surface without knowing which theme is active.

Viewport context adjusts tokens for different screen sizes:

:root {
  --spacing-section: 24px;
}

@media (min-width: 768px) {
  :root {
    --spacing-section: 48px;
  }
}

Container context uses container queries for component-local adaptation:

.card-container {
  container-type: inline-size;
  --card-padding: 12px;
}

@container (min-width: 400px) {
  .card-container {
    --card-padding: 24px;
  }
}

User preference context respects accessibility settings:

:root {
  --motion-duration: 200ms;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-duration: 0ms;
  }
}

Mode context adapts to application states:

:root {
  --spacing-density: 16px;
}

[data-density="compact"] {
  --spacing-density: 8px;
}

Key Considerations

Common Questions

How should context precedence be managed?

When multiple contexts apply simultaneously, precedence determines which value wins.

CSS specificity naturally handles precedence for stylesheet-based contexts. More specific selectors override less specific ones:

:root { --color-primary: blue; }
[data-theme="dark"] { --color-primary: lightblue; }
[data-theme="dark"][data-brand="b"] { --color-primary: cyan; }

Explicit precedence rules should be documented when natural cascade is insufficient:

Context Priority (highest to lowest):
1. Component-local overrides
2. User preferences
3. Brand/theme selection
4. Viewport-based defaults
5. Base values

Avoiding conflicting contexts simplifies reasoning. When possible, contexts should be orthogonal (theme and viewport) rather than overlapping (two different theme systems).

How should contextual tokens be tested?

Testing contextual tokens requires verifying behavior across context combinations.

Automated visual testing captures appearance under different contexts:

// Storybook or similar
export const LightTheme = () => <Component />;
LightTheme.parameters = { theme: 'light' };

export const DarkTheme = () => <Component />;
DarkTheme.parameters = { theme: 'dark' };

Context matrix testing systematically covers combinations:

const contexts = {
  theme: ['light', 'dark'],
  viewport: ['mobile', 'tablet', 'desktop'],
  density: ['normal', 'compact']
};

// Generate all combinations for testing

Unit testing verifies token resolution logic:

test('returns dark value in dark context', () => {
  setContext({ theme: 'dark' });
  expect(resolveToken('color.surface')).toBe('#1a1a1a');
});

Manual testing validates edge cases and transition states that automated tests may miss.

How do contextual tokens affect component architecture?

Contextual tokens shift adaptation responsibility from components to the token layer.

Without contextual tokens, components handle context explicitly:

function Card({ theme, viewport }) {
  const padding = viewport === 'mobile' ? 12 : 24;
  const background = theme === 'dark' ? '#1a1a1a' : '#ffffff';

  return <div style={{ padding, background }}>...</div>;
}

With contextual tokens, components are context-agnostic:

function Card() {
  return (
    <div style={{
      padding: 'var(--card-padding)',
      background: 'var(--color-surface)'
    }}>
      ...
    </div>
  );
}

Context providers establish the context:

<ThemeContext theme="dark">
  <ViewportContext>
    <Card />
  </ViewportContext>
</ThemeContext>

This separation simplifies component code but requires the token system to handle all contextual variations. Components become more reusable since they do not encode context assumptions.

Summary

Contextual design tokens adapt to their environment based on themes, viewport size, user preferences, container dimensions, or application modes. Context-awareness shifts adaptation responsibility from component code to the token layer. Clear precedence rules and thorough testing across context combinations ensure predictable behavior. Contextual tokens enable simpler, more reusable components while supporting sophisticated adaptive interfaces.

Buoy scans your codebase for design system inconsistencies before they ship

Detect Design Drift Free
← Back to Token Management