Skip to content
César Venzac

Springs, in three numbers

Stiffness, damping, mass. A short, practical map of what each one does to the feel of a component — and which two you should actually touch.

1 min readmotion

Spring parameters get tuned by vibes. Somebody drags the stiffness up, the thing feels snappier, they ship it. That works right up until the animation needs to match another one, at which point nobody can say what's wrong.

Here's the whole model, and it really is this small:

  • Stiffness — how hard it pulls toward the target. Higher is faster and more eager.
  • Damping — how much it resists. Higher stops the bounce; too high and it crawls.
  • Mass — how much inertia it carries. Higher overshoots more and settles later.
320
30
1
PresetsClick the square to send it back.
Drag the three values and watch where the box lands.

In practice: leave mass at 1 and forget it exists. Raising mass is almost always a slower way to get the effect you'd get by lowering stiffness, and it makes two springs much harder to match.

motion/springs.ts
export const springs = {
  /** Tooltips, small reveals. Quick, no visible overshoot. */
  snappy: { type: "spring", stiffness: 560, damping: 38, mass: 1 },
  /** Sheets, drawers, anything with size. A hint of settle. */
  smooth: { type: "spring", stiffness: 320, damping: 30, mass: 1 },
  /** Playful, for things the user directly grabbed. */
  bouncy: { type: "spring", stiffness: 420, damping: 18, mass: 1 },
} as const;

One rule worth keeping: if a spring visibly bounces on a surface that contains text, it's wrong. Overshoot on a body of text reads as instability. Save it for handles, toggles, and things the user is holding.