Feel · Motion
Practical tips

Practical tips

Emil Kowalski’s 7 Practical Animation Tips answers his own early belief that animation is an art you either get or you do not. The order is his.

Tips 1 to 3: scale and tooltips#

One: scale your buttons. The interface “should feel as if it’s listening to the user,” and the cheapest feedback is transform: scale(0.97) on :active, which his skill file pairs with a 160ms ease-out transition. In Train Your Judgement 0.9, a tenth of the size, is too much: “If you can clearly see the button shrinking, the scale is too aggressive.”

CSSEmil Kowalski, emil-design-eng SKILL.md
.button {  transition: transform 160ms ease-out;}.button:active {  transform: scale(0.97);}

Two: do not animate from scale(0). Start from 0.9 or above (his demo uses 0.93, his skill table 0.95): a deflated balloon still has a shape, and an element growing from nothing looks like it came out of nowhere. Three: do not delay subsequent tooltips. The first waits to prevent accidental activation; the next opens with no delay and no animation. Radix and Base UI skip the delay; Base UI’s data-instant lets you zero the transition too.

CSSEmil Kowalski, 7 Practical Animation Tips
.tooltip {  transition:    transform 0.125s ease-out,    opacity 0.125s ease-out;  transform-origin: var(--transform-origin);  &[data-starting-style],  &[data-ending-style] {    opacity: 0;    transform: scale(0.97);  }  &[data-instant] {    transition-duration: 0ms;  }}

Tips 4 to 7: easing, origin, speed, blur#

Four is the easing argument from the last section, ease-out for enter and exit. Five: make popovers . A dropdown should scale in from the button that opened it; the default transform-origin: center is wrong in most cases. Radix and Base UI expose variables for this and shadcn/ui wires them; modals keep the center origin because they have no trigger. Whether anyone notices matters less than you would think: “In the aggregate, unseen details become visible, they compound.”

CSSEmil Kowalski, 7 Practical Animation Tips
.radix {  transform-origin: var(--radix-dropdown-menu-content-transform-origin);}.baseui {  transform-origin: var(--transform-origin);}

Six: keep animations fast, which is 2.1 again (the spinner, 180ms versus 400ms, under 300ms), plus: remove animations or hover effects entirely if they are seen tens or hundreds of times a day. Seven: use blur when nothing else works. His demo crossfades a button between two states, once plain and once with 2px of filter: blur(); the blur “bridges the visual gap between the old and new states.” The skill file caps it under 20px; heavy blur is expensive, especially in Safari.

Train Your Judgement adds two. Motion’s AnimatePresence keeps an exiting chip in flow until its animation ends, so siblings wait and then slide; mode="popLayout" pulls it out on the first frame so siblings move in parallel with the exit. And for anything toggled rapidly, prefer transitions over keyframes: keyframes jump mid-play, transitions retarget.

Stagger, short and ranked#

On Emil keeps delays at 30 to 80ms, because long delays make the interface feel slow, and insists stagger is decorative: never block interaction while it plays. His hero exercise is about hierarchy: staggering every element with identical timing feels artificial, “the same effect on motion as a linear easing,” while the better version gives the title the most screen time and lets the least important element just fade.

Rauno Freiberg, in Designing Depth, reaches for nature: a school of fish mesmerises through slight timing differences among identical-looking things. OpenAI staggers the fade-in of grid content, which does not feel slower but stops the user wondering how many items changed; the iPhone unlock staggers the Home Screen apps and makes “a primitive swipe feel three-dimensional.” In the playground, watch the delay multiply by the count: pleasant for four rows, a drag for forty.

Time to settle580ms
  • Item 10 ms
  • Item 240 ms
  • Item 380 ms
  • Item 4120 ms
  • Item 5160 ms
  • Item 6200 ms
  • Item 7240 ms
  • Item 8280 ms
Adjust
Figure 3. Stagger playground. Replay and watch the list enter. The per-item delay multiplies by the count, so a delay that feels right for four items drags for forty. The number shows how long the last item waits before it settles.Illustrative numbers

Stagger only at first contact#

The boundary is frequency again. Rauno calls the Home Screen stagger a first point of contact, “a great moment to especially dial the novelty of animations up a notch,” and in Novelty notes that iOS staggers it only after the first unlock and Paco Coursey’s site only on first load. Emil’s side-panel exercise is the negative case: a panel that slides in and then trickles its items is two layers of entrance, and the better version has the content simply there. “Sometimes the best animation is no animation.”