# Duration and feedback

> 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.

Module: Motion · Level: beginner · 7 min · https://school.agents.org.in/design/motion/duration-and-feedback

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.

*[Interactive demo: One dropdown, one curve. Slide the duration and open it again.]*

The duration (How long an animation lasts. Almost all interface motion belongs under 300 milliseconds; button presses take 100 to 160) 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.

> **If unsure, halve it.** Most animations that "feel slow" are simply too long. Most that "feel jumpy" are too short. When in doubt, halve the number and look again.

## 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.

```css
.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.

*[Interactive demo: Press and hold each one, then let go halfway through.]*

```css
.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.

*[Interactive demo: Hover across the buttons, or tab through them, in both modes.]*

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.

**Durations and feedback (paste into your agent):**

```text
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.
```

**Check yourself:** A panel slides in over 250ms. How long should its exit take?

- [ ] 250ms, exits should mirror entrances
- [x] About 180ms, because the person has already moved on
- [ ] 400ms, so the exit feels gentle
- [ ] 0ms, exits don't need animation

*Why:* Exits are usually 60–80% of the entrance. The person has made their decision; a shorter, quieter exit gets out of the way.

## In the skill

- https://school.agents.org.in/skill/motion/duration-table.md
- https://school.agents.org.in/skill/motion/responsive-feedback.md
