data-slot CSS API
Customize any component internal with CSS — no source ownership, no !important, no forks. 98 data-slot targets across all components.
/* Target the button root */
[data-slot="button"] {
border-radius: 9999px;
}
/* Target the modal overlay */
[data-slot="modal-overlay"] {
backdrop-filter: blur(8px);
}
/* Target the input wrapper */
[data-slot="field-wrapper"] {
margin-bottom: 1rem;
}Key features
98 data-slot targets across all components
Stable, documented CSS hooks — not implementation details
No !important needed — data-slot selectors are specific enough
No component forks — customizations live in your CSS, not the source
Safe across npm updates — your styles persist
Works with Tailwind's arbitrary variant: data-[slot=button]:rounded-full
The customization problem
Copy-paste libraries like shadcn/ui give you source ownership so you can customize anything. But owning source means merge conflicts on every update. Ninna UI takes a different approach: you customize through CSS data-slot targets, not source edits.
Every component internal has a data-slot attribute. These are stable, documented CSS hooks — not implementation details that might change. You target them in your CSS, and your customizations persist across npm updates.
Using data-slot with Tailwind
You can use data-slot selectors with Tailwind's arbitrary variant syntax for inline customization:
<Button className="data-[slot=button]:rounded-full">
Pill button
</Button>
<Input className="data-[slot=input]:border-2" />