Motion2 min read
Making React animations feel physical, not scripted
Easing curves describe a path. Springs describe a force. Once you stop choreographing pixels and start giving them mass, interfaces begin to feel like objects instead of slideshows.
Every interface animation answers a question the user did not ask out loud: where did that thing come from, and where did it go? An easing curve answers with a schedule. A spring answers with a force. Only one of those matches how objects behave in the world your users spend the other twenty-three hours of their day in.
Why easing curves fail under the finger
A cubic-bezier is a promise about duration. The moment a user interrupts it — drags the sheet back down, taps the menu again before it has opened — that promise breaks. You get a jump, or a reversal that starts from zero velocity as if the previous motion never happened.
Springs carry velocity across interruptions for free. The sheet you flicked upward keeps its momentum when you catch it. There is no special case to write, because continuity is the default rather than a feature you bolt on.
const { y } = useSpring({
from: { y: 420 },
config: { mass: 1, tension: 180, friction: 24 },
immediate: prefersReducedMotion,
})The three numbers that matter
Mass, tension and friction. Mass is how heavy the thing feels, tension is how eagerly it wants to arrive, friction is how quickly it stops arguing about it. I almost never touch mass — it is the one that makes motion feel sluggish rather than weighty.
If you cannot interrupt your animation halfway and have it still look right, it is choreography, not interaction.
Tuning by feel
Start from tension 180 and friction 24, then change one at a time while watching the thing at quarter speed. A spring that overshoots by two or three percent reads as alive. One that overshoots by fifteen reads as broken.
Respecting reduced motion
- Treat
prefers-reduced-motionas a first-class branch, not a media query you bolt on at the end. - Keep opacity transitions — motion sensitivity is about movement, not about things appearing.
- Snap to the end state instead of shortening the duration. A fast animation is still an animation.
What I ship today
One spring configuration per product, exported from the design system, with three presets: snappy for controls, gentle for surfaces, and stiff for anything that follows a finger. Three presets cover roughly ninety percent of what an interface needs, and the remaining ten percent is where the interesting work lives.
- Motion
- React
- Design Systems
- Accessibility