CSS variable fallbacks
How Rad UI uses CSS custom properties in tokenized theme layers, and what consumers can rely on when building custom styles.
Rad UI is headless by default. The core component library does not require CSS variables. Variables matter when you use Rad UI's default theme CSS, token outputs, or your own design-system layer on top of documented data-* hooks.
Where variables come from
When you import @radui/ui/themes/default.css, token values are defined as --rad-ui-* custom properties (see styles/cssTokens/ in the repository).
Theme also exposes public metadata on its container:
data-rad-ui-theme— resolved appearance (light/dark)data-rad-ui-accent-color— active accent palette namedata-rad-ui-radius— radius scale selectiondata-rad-ui-scaling— density / scale selection
Default theme selectors use these attributes to scope accent palettes and semantic colors.
Supported consumer contract
Consumers may rely on:
- documented
data-*attributes listed in component docs and Usage --rad-ui-*variables after importing a Rad UI theme stylesheet or defining equivalent variables themselvesThemeattribute values when styling subtrees with your own CSS
Consumers should not rely on:
- undocumented internal class names when
classNamespaceis not set - private DOM structure beyond public anatomy parts
- variables that only exist incidentally in generated CSS without being part of the token contract
Fallback strategy
Use standard CSS fallback syntax when a variable might be missing during incremental adoption:
Guidelines:
- Import theme CSS for the subtree that should use Rad UI tokens, or define the same
--rad-ui-*names yourself. - Scope overrides under
Themeso accent and appearance selectors stay predictable. - Provide fallbacks in app-level CSS when mixing Rad UI tokens with legacy styles during migration.
- Prefer semantic tokens (
--rad-ui-color-gray-100) over hard-coded component internals.
Partial theme adoption
You can use Rad UI headlessly and define only the variables your app needs:
Components without the default stylesheet will not auto-apply these values. Your CSS must reference the variables explicitly.
Nested Theme providers
Each Theme subtree can set its own accent, radius, and scaling attributes. CSS that keys off data-rad-ui-accent-color applies within the matching subtree only.
When overriding variables for a nested section, set them on the inner theme container:
Component-level animation variables
Some components expose measured dimensions as CSS variables for consumer-driven animation (for example accordion content height). Treat those variables as part of the component's documented styling surface when listed on the component page.
Checklist for custom design systems
- Decide whether you import Rad UI theme CSS or mirror the
--rad-ui-*contract yourself. - Style through
data-*attributes and documented variables, not internal selectors. - Add fallbacks for any variable your app uses before theme CSS loads.
- Test light/dark and nested
Themescopes when overriding accent tokens.