Ease vs Spring: two languages of motion
When designing motion, the most common question is: “what easing should I use here?” The right answer depends on one thing only — is the thing that’s moving physical or electronic?
Click Play to run both at the same time
Ease — electronic motion
Ease is a mathematical function. ease-out is defined by a cubic-bezier whose control points lie within [0, 1] — meaning the output value never goes outside the start–end range.
/* Common presets */
ease-in: cubic-bezier(0.42, 0, 1, 1)
ease-out: cubic-bezier(0, 0, 0.58, 1)
ease-in-out: cubic-bezier(0.42, 0, 0.58, 1)
Behavior: it starts, accelerates or decelerates along the curve, and stops exactly at the target. Nothing happens after it arrives.
When to use: UI elements with no physical weight — fade in/out, opacity changes, color transitions, page transitions. Things that “appear” or “disappear” rather than “move.”
Spring — physical motion
A spring simulates real physics: a mass attached to a spring. When pulled and released, it returns to its equilibrium point but carries inertia — overshooting the target, bouncing back, oscillating around equilibrium before finally settling.
In CSS, a spring is approximated by a cubic-bezier with a control point y > 1:
/* Spring — control point 1.56 creates ~17% overshoot */
cubic-bezier(0.34, 1.56, 0.64, 1)
The value y = 1.56 makes the output exceed 1.0 (that is, overshoot the endpoint) before returning to 1.0 to settle.
When to use: Elements with “weight” or that respond to direct manipulation — toggle thumbs, like buttons, popups, drawers, toasts. Things the user “pushes,” “drags,” or “presses.”
Why the difference matters
Overshoot in a spring is not a bug — it’s a physical signal. When a toggle thumb bounces slightly past its stopping point, the user’s brain registers: “this has mass, it’s real.” This is why physical UIs (iOS toggles, Android bottom sheets) use springs while digital UIs (modal backdrops, tooltips) use ease.
Conversely, using a spring for something that shouldn’t have weight (e.g. a fade overlay, a loading state) creates a strange feeling — as if the darkness itself were “bouncing.”
Quick reference table
| Situation | Use | Reason |
|---|---|---|
| Toggle switch thumb | Spring | Physical, has weight |
| Modal backdrop fade | Ease | No mass |
| Like button scale | Spring | Direct response to a tap |
| Page transition | Ease | A scene change, not an object |
| Bottom sheet slide up | Spring | Direct manipulation |
| Tooltip appear | Ease | Appears, doesn’t move |
| Drag-and-drop drop | Spring | An object falling into place |
| Skeleton loader fade | Ease | A loading state, not physical |
Same duration, two different results
Both animations in the demo run for 0.7 seconds with the same start and end points. The difference lies entirely in the path — ease goes straight (mathematical), spring loops past and comes back (physical).
A long duration does not automatically produce a better “feel.” A 0.3s spring is often better than a 0.8s ease if placed in the right spot.