Duration and feedback
beginner·7 min·Markdown for agents
What this lesson teaches
Choose how long an animation should last for each kind of element, and add the small press and tooltip responses that make UI feel answered.
Drag the slider to 600ms and open the menu. Then try 200ms. Same curve, same menu: one is a small show, the other just answers you.
The is how long the animation lasts. There is no single right number; it depends on what is moving and how often people see it. But there are good ranges, and almost all UI motion belongs under 300 milliseconds.
The table
| Element | Duration |
|---|---|
| Button press | 100–160ms |
| Hover change | 120–200ms |
| Tooltip | 125–200ms, after a first delay |
| Dropdown or popover | 150–250ms |
| Modal | 200–300ms |
| Tab content swap | 200–250ms |
| Page transition | 250–400ms, the longest normal UI motion |
| Skeleton to content | 150ms |
| Celebration, confetti | 600–1200ms (rare, so it can afford it) |
| First-run onboarding | 400–800ms |
Three rules of thumb cover anything not on the list. Smaller is shorter: a 12px icon doesn't need 300ms. More frequent is shorter. More important is a little longer: a modal changes what you're looking at, so it earns more time than a tooltip.
Exits are shorter than entrances
When something closes, the person has already moved on. Make the exit about 60 to 80 percent of the entrance: a panel that opens in 250ms closes in about 180ms.
.panel { transition: transform 180ms var(--ease-out); } /* closing */
.panel[data-state="open"] { transition-duration: 250ms; } /* opening */Use transitions here, not keyframes. A transition starts from wherever the element is right now, so if someone closes the panel halfway through opening, it simply turns around. A keyframe animation would jump back to its first frame.
There's a second kind of asymmetry for moments where the person is deciding. A hold-to-delete button fills slowly while you hold (2 seconds, linear) and snaps back fast if you let go (200ms, ease-out). The slow part is their decision; the fast part is the system answering. You'll build that in the choreography lesson.
Sonner's toasts run a calm ~400ms on purpose. That's a personality choice, not the default.Press feedback
The smallest animation with the biggest effect: a button that shrinks a little under your finger. Press and hold each of these.
Press and hold each one. Then let go halfway: the good one glides back because it is a transition, not a keyframe.
.button { transition: transform 120ms var(--ease-out); }
.button:active { transform: scale(0.97); }The canonical numbers: 0.97 for buttons, 0.96 for small controls like icon buttons and chips, and never below 0.95, where it starts looking squishy. Keep it 100–160ms. Because it's a transition, a release mid-press glides back. Two exceptions: text inputs don't scale (shift the border or background instead), and controls used hundreds of times a day can skip it.
Tooltips that don't make you wait twice
Tooltips need a delay before the first one appears, roughly 400–700ms, so a pointer passing over a toolbar doesn't spray labels everywhere. But once one is open, the neighbours should appear instantly, with no delay and no animation. Move across this toolbar with each setting.
Hover across the buttons (or tab through them). With the skip on, only the first one makes you wait.
This "skip delay" is one of the most reused details in good interfaces; without it, exploring a toolbar feels gluey. Radix UI's tooltip provider has it built in (skipDelayDuration), and sets a data-instant attribute you can use to drop the animation. Give tooltips and hover popovers a small close delay too, about 150ms, so a slight wobble of the mouse doesn't make them flicker.
One more responsiveness rule lives with popovers: a menu should grow out of the button that opened it. That's the next lesson.
Check every transition in this UI against these budgets: button press 100–160ms, hover 120–200ms, dropdowns and popovers 150–250ms, modals 200–300ms, page transitions up to 400ms. Make exits about 70% of the entrance duration, using transitions (not keyframes) so they can reverse mid-way. Add :active { transform: scale(0.97) } with a 120ms ease-out to buttons (0.96 for icon buttons), but not to text inputs. Give tooltips a ~500ms first delay and make neighbouring tooltips appear instantly while one is open.Quick check
A panel slides in over 250ms. How long should its exit take?
In the skill
The nodes your agent reads when it does this work.
Connected lessons
What this lesson builds on and leads to, across every course.