Motion
Choose a duration, an easing, and an animation utility for an overlay, a mark, or a panel.
Motion in the kit is behavior and no look retunes it. This page gives the two durations, the one easing, and the animation utilities, and then the rules for which animation an overlay uses, so a new popper, dialog, or panel moves like the ones around it.
Two durations cover everything. --duration-fast is 120ms and is used for control marks and for the fade of sidebar labels. --duration-base is 200ms and is used for everything else. The easing is --ease-out, which is cubic-bezier(0.16, 1, 0.3, 1).
Utilities
| Utility | Does | Duration |
|---|---|---|
animate-fade-in and animate-fade-out | Opacity | base |
animate-pop-in and animate-pop-out | Opacity and scale from 0.96 to 1 | base |
animate-check-in | Opacity and scale from 0.5 to 1 | fast |
animate-slide-in-right, -left, -top, and -bottom, with matching animate-slide-out-* | translate from or to the edge | base |
animate-accordion-down and -up | Height, from the Radix accordion content height | base |
animate-collapsible-down and -up | Height, from the Radix collapsible content height | base |
The fade-out, pop-out, and slide-out utilities hold their end state. Pop animates scale and the slides animate translate, so neither stacks on the transform that a popper or a centered dialog already uses. The keyframes are named dry-* in bindings.css, so do not add tw-animate-css.
animate-fade-inanimate-pop-inanimate-check-inOverlay rules
Do not animate transform on a popper or a centered overlay. Radix poppers position themselves with transform, and dialogs center with -translate-x-1/2 -translate-y-1/2, so animating transform on top of those makes the panel jump.
| Overlay | Motion | Reason |
|---|---|---|
| Dropdown menu, context menu, select, tooltip, popover, hover card | Fade only | The popper transform stays intact |
| Dialog and alert dialog | Fade the overlay and pop the content | Pop uses scale |
| Sheet | Fade the overlay and slide the content | Slide uses translate |
| Accordion and collapsible | Height keyframes | They animate to the measured content height |
| Checkbox mark | animate-check-in | It is a control mark, so it uses the fast duration |
className={cn(
"data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out",
"motion-reduce:animate-none",
)}Components that move on their own
- Tabs moves its active line so that the leading edge travels first and the mark stretches, then the trailing edge catches up. The lead is
--duration-fastand the trail is--duration-base, both on--ease-out. - Sidebar collapses to icons in CSS. The panel and each row tween their width on
--duration-baseand--ease-out. - WorkMark and PriorityBars use one spring (stiffness 420, damping 40, mass 0.9). Marks that change together stagger by 28ms, and a mark on first render appears without animating.
- Interactive card lifts, zooms its media, or reveals its actions on hover and focus, on
--duration-baseand--ease-out. Reduced motion leaves the card still and keeps the actions visible.
Accessibility
- The overlay components pair each animation utility with
motion-reduce:animate-none, so a reader who prefers reduced motion gets overlays that appear without animating. Add the same class to any new use of these utilities. - The Tabs line, WorkMark, and PriorityBars check the reduced motion preference in code and jump to their end state, and the Sidebar width tween carries
motion-reduce:transition-none. - Interactive card's lift, zoom, and reveal run only under
motion-safe, so reduced motion leaves the card still and keeps its actions visible. The lift shadow still steps, with no transition.
Next
Elevation covers the shadows that the pop and slide overlays carry. Dialog, Sheet, and Popover show the overlay patterns in place.