Transitions

A transition animates a property smoothly from one value to another when it changes — on hover, focus, a class toggled by JavaScript, or a media query. Small, quick transitions make interfaces feel responsive and polished.

A basic transition

Try it yourself
Result

The transition goes on the element's normal state, so it runs in both directions — when the hover starts and when it ends.

Transition properties

PropertySetsExample
transition-propertyWhich properties animatebackground-color, transform
transition-durationHow long0.2s, 300ms
transition-timing-functionThe speed curveease, linear, ease-out
transition-delayWait before starting0.1s
CSS shorthand.css
.card {
  /* property duration timing-function delay */
  transition: transform 0.2s ease-out, box-shadow 0.2s ease-out 0.05s;
}

Avoid transition: all: it animates properties you didn't intend, and costs performance. List the properties explicitly.

Timing functions

Try it yourself
Result

From top: linear, ease (the default), ease-in, ease-out, and a custom cubic-bezier() that overshoots. ease-out feels natural for things entering or responding to the user; steps(n) creates frame-by-frame motion, and linear() can describe springy curves point by point.

Good transition habits

  • Keep UI transitions short: about 150–300ms. Longer feels sluggish.
  • Animate transform and opacity when possible; they're the smoothest.
  • Respect users who prefer less motion (below).

Transitioning to and from display: none

Try it yourself
Result

transition-behavior: allow-discrete (here, the allow-discrete keyword in the shorthand) lets display participate in a transition, and @starting-style defines where an entering element animates from. Together they make enter and exit animations possible without JavaScript timing tricks.

Animating height to auto

Try it yourself
Result

Historically, CSS couldn't transition to height: auto. Newer browsers support it with interpolate-size: allow-keywords (or the calc-size() function). In browsers without support, the panel simply opens instantly.

Reduced motion

CSS reduced-motion.css
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

Some people experience dizziness or nausea from motion on screen, and set a system preference to reduce it. Honour it — this snippet is a common global safety net.

Try it yourself

Try it yourself
Result