Physics-based motion

Why springs feel better than cubic-bezier curves

A CSS transition follows a predetermined path. A spring responds to forces: target position, damping resistance, inertia.

Retarget a spring mid-flight and the velocity carries over. A CSS transition interrupted mid-flight either jumps or snaps.

The three parameters

Stiffness controls speed. 100 = lazy, 500 = snappy, 700+ = hard snap.

Damping controls resistance. 15 = visible bounce, 40 = smooth settle. Low = playful, high = professional.

Mass controls weight. 0.5 = zippy, 2 = heavy. Stay between 0.5 and 1.5.

Useful presets

PresetStiffnessDampingUse case
Snappy50040General UI, no bounce, fast settle
Bouncy30020Playful elements, notification badges
Gentle20030Page transitions, large panels
Stiff70050Small precise movements, toggles

In product UI, bounce above 0.3 reads as cartoonish.

The Apple-style parameterisation

Apple uses duration and bounce instead of stiffness, damping, and mass.

Motion supports both.

SwiftUI's .spring(response: 0.35, dampingFraction: 0.85) maps to Motion's { type: "spring", duration: 0.35, bounce: 0.15 }.

Interruptibility

Every drag, gesture, or interruptible element should use springs.

Velocity inheritance

When a user flicks a card and a snap point catches it, the velocity should transfer to the spring.

Conceptual weight

Mass is a design decision about perceived importance. A 0.5 mass tooltip zips into view. A 1.5 mass modal settles deliberately. Destructive actions get critically damped springs (no bounce). Playful moments get underdamped springs (visible overshoot).

When not to use springs

In code