All guides

Spring Animations Explained: Stiffness, Damping and Mass

By Hizmedia · · 6 min read

Springs are why some interfaces feel physical and others feel like slideshows. Instead of moving from A to B over a fixed time, a spring pulls an element towards its target with a force, and the motion is whatever that force produces: a quick settle, a gentle overshoot or a lively wobble. Three numbers control it. Drag them below and watch what each one does.

Try it

Spring lab

Damping ratio 0.46: under-damped, so it overshoots and wobbles. Settles in about 1.04s.

spring.tsx
<motion.div
  animate={{ x: 240 }}
  transition={{ type: "spring", stiffness: 170, damping: 12, mass: 1 }}
/>

The ball and the curve use the same three values. The curve plots the ball's position over two seconds; the dashed line is the target.

What the three numbers do

A spring animation simulates a weight on a spring. Every frame, two forces act on it: the spring pulls it towards the target, harder the further away it is, and damping resists its speed, like friction.

  • stiffness: how strongly the spring pulls. Higher values make the motion faster and snappier.
  • damping: how much the motion is resisted. Low damping lets it overshoot and oscillate; high damping makes it settle without overshooting, and very high damping makes it sluggish.
  • mass: how heavy the thing being moved is. More mass makes it slower to start and stop, and adds momentum to any overshoot.

The damping ratio: wobble or no wobble

Whether a spring overshoots depends on the three values together, through the damping ratio: damping divided by 2 × √(stiffness × mass).

  • Below 1, the spring is under-damped: it overshoots and oscillates before settling. Values around 0.5 to 0.8 feel lively without being silly.
  • At 1, it's critically damped: the fastest possible settle with no overshoot at all.
  • Above 1, it's over-damped: it creeps into place, which can feel heavy.

This is why doubling stiffness alone makes a spring bouncier as well as faster: the ratio drops. To keep the same feel while speeding it up, raise damping too.

Springs in Motion

In Motion, set type: "spring" on a transition and give it the physical values:

button.tsx
<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  transition={{ type: "spring", stiffness: 400, damping: 17 }}
/>

If you'd rather think in time, Motion also accepts a duration and a bounce instead, and works out the physics for you. bounce runs from 0 (no overshoot) to 1 (very springy).

example.tsx
transition={{ type: "spring", visualDuration: 0.4, bounce: 0.25 }}

Why springs feel better when interrupted

The real advantage of springs shows when an animation is interrupted. If someone hovers off a button halfway through its grow, a fixed-duration tween has to start a fresh animation from a standstill, which can look like a hiccup. A spring keeps its current velocity and simply heads for the new target, so the motion stays continuous. That's why springs suit anything that follows the pointer, a finger or a drag: magnetic buttons, sliders, docks and tilting cards.

Picking values

  • Snappy UI feedback, such as buttons and toggles: stiffness 300 to 500, damping 20 to 30.
  • Panels, menus and layout changes: stiffness 200 to 300, damping 25 to 35, little or no overshoot.
  • Playful elements that should wobble: stiffness 150 to 250, damping 8 to 14.
  • Things that follow the pointer: lower stiffness (100 to 200) so they trail with some weight.

With reduced motion on, swap springs that move things across the screen for an instant change or a short fade. Small scale changes on press are generally fine to keep.