Skip to content
Motion & micro-interactionsLesson 3 of 8Intermediate9 min

Easing & spring

Easing scripts a move over a fixed time; a spring simulates physics and settles on its own. Knowing which to reach for is half of good motion.

Kept on this device only.

In one line: reach for an easing curve when you want a move to take a known amount of time, and a spring when you want it to feel like a physical object responding to force.

What it is

Easing describes how an animation's speed changes across a fixed duration. You pick a curve — ease-out, ease-in-out, a custom cubic-bezier() — and a time, say 300 ms, and the browser interpolates between start and end along that curve. Nothing overshoots; the move ends exactly when the clock says so.

A spring is different in kind: instead of a duration, you describe a little physics model — stiffness (how hard it pulls toward the target), damping (how much it resists motion), and mass — and let it run until it settles. A spring can overshoot the target and oscillate before coming to rest, which is exactly what makes motion feel physical.

Why it matters

The choice changes how an interface feels. Easing is predictable and calm: good for things that should feel deliberate — a panel sliding open, a page transition, anything where a consistent, knowable duration matters. A spring is reactive and alive: good for direct manipulation — dragging, pressing, snapping — where the motion should echo a real force the user applied.

The common mistake is using a long ease where a spring belongs (the interface feels sluggish and scripted) or a bouncy spring where calm easing belongs (everything wobbles and reads as toy-like). Match the curve to the cause.

See it

Live demo
Tweak it3
600
12
0.6
Compare a spring to a fixed ease. Move the box, then tune the spring.

How it works

Two mental models, side by side:

  1. Easing = a path through time. The curve below maps elapsed time (left to right) to progress (bottom to top). ease-out starts fast and decelerates — it feels responsive because most of the distance is covered early.
Easing · ease-out
ease-out: fast start, gentle landing. No overshoot.
  1. A spring = a simulation. There's no fixed end time; stiffness and damping decide how quickly it settles and whether it overshoots. Lower damping means more wobble.
Spring · stiffness 600, damping 12, mass 0.6
A spring overshoots past the target, then settles.

Tune a spring by feel: raise stiffness for a snappier arrival, lower damping for more bounce, and keep the settle time short enough that it never adds perceived latency.

Build it

Easing in CSS — a fixed-duration ease-out
.card {
  transform: translateX(0);
  transition: transform 300ms cubic-bezier(0, 0, 0.58, 1); /* ease-out */
}
.card.is-moved {
  transform: translateX(180px);
}
 
/* CSS has no real spring, but a tuned cubic-bezier can fake a small overshoot. */
.card.springy {
  transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); /* slight overshoot */
}
 
@media (prefers-reduced-motion: reduce) {
  .card,
  .card.springy {
    transition: none;
  }
}

Make it yours

Use the controls beside the demo above to change stiffness, damping, and mass — each change updates the example live.

Experiment in the playground

Reproduce it with an LLM

Reproduce it with an LLM

You are a senior front-end engineer. Build two versions of the same 'move a card 240px to the right on click' interaction in React using the Motion library: one with a fixed-duration ease-out (about 300 ms), and one with a spring. For the spring, expose stiffness, damping, and mass as props and pick defaults that settle in roughly 400 ms with a small, tasteful overshoot. Requirements: animate only transform; fully disable animation under prefers-reduced-motion: reduce; keep the control a real button with a visible focus-visible ring. Add a one-line code comment on each that says when to prefer it. Return only the component code with imports.

Pitfalls & accessibility

Further reading

  • Your animation library's spring documentation, for how stiffness, damping, and mass map to feel.
  • A primer on cubic-bezier() timing functions and how to read an easing curve.