Modern CSS Theme Architecture
Build theme systems that are accessible, maintainable, and adaptable by separating design decisions from implementation details.
Why this matters
Many websites still treat theming as a simple choice between a light and dark colour palette. Modern CSS has evolved beyond this model.
A well-designed theme architecture allows websites to:
- Respect user preferences.
- Support multiple themes without duplicating CSS.
- Improve maintainability through semantic design tokens.
- Make accessibility easier to audit and improve.
- Adapt to future browser capabilities with minimal changes.
This document describes the architectural principles behind modern CSS theming. It complements, rather than replaces, accessibility guidance on colour contrast, dark mode, focus indicators, reduced motion, and other user preferences.
Architecture Overview
A modern theme system separates user preferences from implementation.
User Preferences
│
▼
Browser Capabilities
│
▼
Theme Resolution
│
▼
Semantic Design Tokens
│
▼
Component Tokens
│
▼
Component Implementation
Each layer has a distinct responsibility.
Respect User Preferences
Users may express preferences through their operating system, browser, assistive technology, or application settings.
Common preferences include:
- Light mode
- Dark mode
- Forced colours
- Increased contrast
- Reduced motion
- Reduced transparency
- Larger text
- Browser zoom
- Custom stylesheets
A modern theme architecture should respect these preferences whenever possible.
Application-specific preferences should complement, rather than replace, operating system preferences.
Prefer Native Browser Features
Modern browsers increasingly support adaptive theming directly.
Examples include:
color-schemelight-dark()prefers-color-schemeprefers-contrastforced-colors
Prefer browser-native functionality before introducing JavaScript.
Native browser support generally provides:
- Better performance
- Lower maintenance
- Better interoperability
- Improved accessibility
Design Layers
Primitive Tokens
Primitive tokens define raw design values.
Examples include:
--blue-500
--gray-100
--gray-900
--spacing-4
--radius-small
Primitive tokens should rarely be referenced directly by components.
Semantic Tokens
Semantic tokens describe purpose rather than appearance.
Good examples:
--surface
--surface-raised
--text-primary
--text-secondary
--interactive
--border-default
--focus-ring
Avoid names tied to colours.
Poor examples:
--blue-button
--light-gray
--dark-background
Semantic names remain meaningful even when themes change.
Component Tokens
Component tokens map semantic tokens onto individual components.
Examples:
--button-background
--button-text
--card-background
--navigation-border
Component tokens should usually reference semantic tokens rather than raw colours.
Theme Resolution
Modern CSS increasingly allows themes to be resolved automatically.
Rather than maintaining duplicated stylesheets:
@media (prefers-color-scheme: dark) {
...
}
consider using:
color: light-dark(#222, #eee);
where browser support permits.
This reduces duplication and simplifies maintenance.
Accessibility Tokens
Accessibility involves more than colour.
Modern design systems should expose tokens for:
Focus
--focus-ring-color
--focus-ring-width
--focus-ring-offset
Borders
--border-width
--border-strong
Motion
--animation-duration
--transition-duration
--motion-scale
Spacing
--target-size
--interactive-spacing
Typography
--reading-width
--line-height-body
Treat these as first-class design tokens rather than hard-coded component values.
Theme Components
A complete theme usually affects much more than colours.
Typical themed elements include:
- Page background
- Raised surfaces
- Text
- Links
- Buttons
- Forms
- Navigation
- Tables
- Borders
- Dividers
- Focus indicators
- Shadows
- Icons
- Charts
- Status colours
- Code blocks
- Syntax highlighting
Avoid treating them as independent colour choices.
Avoid Separate Design Systems
A light theme and dark theme should not become separate design systems.
Instead:
Semantic token
↓
Browser resolves value
↓
Component consumes token
Only the resolved value changes.
The meaning remains constant.
Auditability
Semantic tokens improve accessibility auditing.
Instead of identifying hundreds of colour values across a website:
#005ea5
identify the semantic decision:
--interactive-primary
Fixing one token can improve accessibility across thousands of pages.
Large websites, government platforms, and design systems particularly benefit from this approach.
Progressive Enhancement
Recommended implementation order:
- Semantic design tokens
- Browser-native features (
color-scheme,light-dark()) - User preference media queries
- JavaScript overrides where necessary
Each layer should enhance, rather than replace, the previous layer.
Browser Support
Modern CSS features continue to evolve.
When using newer functionality:
- Prefer progressive enhancement.
- Avoid requiring JavaScript where CSS is sufficient.
- Provide sensible fallbacks.
- Test across supported browsers.
Relationship to Other Accessibility Guidance
This document provides architectural guidance.
For implementation details, see:
- USER_PERSONALIZATION_ACCESSIBILITY_BEST_PRACTICES.md — user preference controls and CSS media queries
- COLOR_CONTRAST_ACCESSIBILITY_BEST_PRACTICES.md — contrast requirements and CSS patterns
- LIGHT_DARK_MODE_ACCESSIBILITY_BEST_PRACTICES.md — light and dark theme implementation
- Focus indicator guidance in the manual testing guide
- Reduced motion guidance in the user personalization guide
- Forced colours guidance in the color contrast guide
Those documents explain how to implement accessible interfaces.
This document explains how to structure a theme system so those recommendations become easier to apply consistently.
Key Principles
Modern CSS theme architecture should:
- Respect user preferences.
- Prefer semantic design tokens over colour-specific names.
- Use browser-native features whenever practical.
- Minimize duplicated theme definitions.
- Treat accessibility as part of the design system rather than a separate concern.
- Improve maintainability through clear abstraction layers.
- Make accessibility easier to audit at scale.
See Also