Skip to main content

Overview

Radix UI Primitives are designed to be styled however you want. They ship with zero presentational styles, giving you a clean slate to build your design system.
No CSS is included. No styles need to be overridden. No specificity battles. Just pure, unstyled components ready for your design.

Zero Styles Philosophy

Radix components render with no default styling—only the minimal browser defaults remain.

Why Zero Styles?

Traditional component libraries force you to:
  1. Override opinionated styles - Fight specificity wars
  2. Import unwanted CSS - Bloat your bundle
  3. Work within constraints - Limited to pre-made designs
  4. Use specific tools - Locked into their styling system
Radix takes a different approach:
  • ✅ No styles to override
  • ✅ No CSS imports required
  • ✅ Complete design freedom
  • ✅ Any styling solution works
Radix handles the hard parts (accessibility, behavior, keyboard interaction) and leaves styling entirely to you.

What You Get

Out of the box, components provide:
  • Semantic HTML structure - Proper element hierarchy
  • ARIA attributes - Full accessibility
  • Data attributes - Hooks for state-based styling
  • Event handlers - Complete interaction logic
  • Keyboard navigation - Built-in keyboard support
Everything except visual appearance.

Styling Approaches

Radix works with any styling solution. Choose what fits your project.

Plain CSS

Use regular CSS classes:

CSS Modules

Scoped styles with CSS Modules:

Tailwind CSS

Utility-first styling:

CSS-in-JS (Styled Components, Emotion)

Vanilla Extract

Type-safe CSS:

Inline Styles

Direct style objects:
Choose the styling solution that matches your team’s preferences and project requirements. Radix doesn’t care which you use.

Data Attributes for State

Radix components expose their internal state through data attributes, making state-based styling straightforward.

Common Data Attributes

data-state

Represents the component’s current state:
Style based on state:

data-disabled

Present when the component is disabled:

data-orientation

Indicates layout direction:

data-highlighted

Present when an item is highlighted (e.g., in menus):

Component-Specific Attributes

Each component may expose additional attributes. Check the component’s documentation for a complete list. Example: Accordion From packages/react/accordion/src/accordion.tsx:314:
Example: Dialog From packages/react/dialog/src/dialog.tsx:109:

Advanced Styling Patterns

Animating State Changes

Use CSS animations with data attributes:
Radix provides CSS variables like --radix-accordion-content-height for smooth animations. See component documentation for available variables.

CSS Variables from Components

Some components expose CSS custom properties:
From packages/react/accordion/src/accordion.tsx:491:

Focus Styles

Add accessible focus indicators:

Hover States

Style interactive elements:

Responsive Styles

Adapt to screen sizes:

Theming

Implement design systems with CSS variables:

Best Practices

1. Use Data Attributes for State

Don’t add your own state classes—use the data attributes Radix provides.
Avoid:
Instead:

2. Maintain Accessibility

Don’t remove focus indicators:

3. Consider Touch Targets

Ensure interactive elements are large enough:

4. Test with User Preferences

Respect user settings:

Real-World Example

Complete styled Dialog component:

Summary

Radix UI’s zero-styles approach gives you:
  • Complete freedom - Style however you want
  • Any tooling - Use your preferred styling solution
  • State hooks - Data attributes for state-based styling
  • No overhead - Zero CSS to download or override
  • Full control - Every visual aspect is yours to design
Start with the structure Radix provides, then add your styles. You’re building on a solid, accessible foundation.