Skip to Content
HTML and CSS Advanced: Styles That Hold Up in Production
Advanced
0 likes
Courses
HTML and CSS Advanced: Styles That Hold Up in Production

Transitions and Animations That Don't Annoy People

Choose what to animate, how long it should take, and when to stop, with the WCAG rules for moving content. After this, motion tells the user something or it does not ship.

Course content

Sign in to save your progress.

Course Home

Skip ahead: If you already limit transitions to transform and opacity, avoid transition: all, and know the WCAG rule for moving content, skip to "Rules for motion that lasts", then continue.

Motion is feedback. A button that dips slightly when pressed tells you the click registered. A panel that slides in tells you where it came from. Motion that does neither, such as a logo that bounces forever or a card that spins on hover, is decoration, and decoration is the first thing people stop tolerating. The test is simple: if you removed the animation, would the user lose information? If not, keep it short or drop it.

Pick what you animate

.btn {
  transition: transform 150ms ease-out, background-color 150ms ease-out;
}

.btn:hover { background-color: #0238c4; }
.btn:active { transform: translateY(1px); }

Animate transform and opacity when you can. Changing them does not force the browser to recalculate layout. Animating width, height, top or margin does, and the whole page may reflow on every frame. Colour changes are cheap enough for hover states.

Why transition: all bites

/* Avoid */
.card { transition: all 300ms; }

/* Better */
.card { transition: box-shadow 200ms ease-out, transform 200ms ease-out; }

With all, anything that changes on that element animates, including things you did not plan. Add a border-width change to the hover state later and it animates too. List the properties you mean.

A keyframe animation that stops itself

@keyframes nudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(4px); }
}

.hint {
  animation: nudge 600ms ease-in-out 2;
}

The last number is the iteration count. The hint plays twice and stops. animation-iteration-count: infinite on something next to body text keeps pulling the eye away from the sentence the reader is trying to finish.

Durations that fit the job

There is no official table. As a working range, 100 to 200 ms suits small feedback like hover and press, and 200 to 300 ms suits things that move across the screen, like menus and drawers. Longer than about 400 ms starts to feel like waiting. Leaving, or closing, can be a bit shorter than entering. I would rather tune these by clicking through the page than defend a number.

Rules for motion that lasts

WCAG 2.2.2 says moving content that starts automatically, lasts more than five seconds and sits beside other content needs a way to pause, stop or hide it. Carousels and looping background videos are the usual offenders. WCAG 2.3.1 sets a limit on content that flashes more than three times in one second. Both are about people who can be made ill or unable to read by the page.

⚠ Warning: Do not hide important content behind an animation. If a form field only becomes usable after a 600 ms slide, you made every user wait for a visual effect.

Common mistakes

  • Using transition: all on components, then adding a property that should snap.
  • Animating height from 0 to auto. It does not interpolate that way by default, so people reach for max-height and then get a delay that depends on the guessed value. Newer Chrome versions can opt in with interpolate-size, so check support before you rely on it.
  • Setting will-change on everything. It reserves memory for each element. Add it to the one element that janks, after measuring.
  • Making hover the only trigger. Touch and keyboard users never see it, so the information must be there without it.

💡 Tip: If an animation looks fine on your laptop and janky on a phone, record it in the DevTools Performance panel. Look for layout work on every frame. That is the sign you animated the wrong property.

What happens if you skip this

The page works, then someone with a vestibular disorder opens it and has to leave. Or the page works for everyone, but a long animation on every menu makes it feel slow, and nobody can say why.

Try it

Take one hover effect on your site. Rewrite it to animate only transform and one colour, and set a duration of 150 ms. Compare it with the old version side by side.

Which animation on your site would nobody notice if it were gone?

About

Choose what to animate, how long it should take, and when to stop, with the WCAG rules for moving content. After this, motion tells the user something or it does not ship.

Duration
5 min
Last update
08/11/2026
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.