Every animation in your UI has two components: what moves and how it moves. We obsess over the first part. Which element, which property, how far. But the second part, the easing curve, is where the actual design happens.
An easing curve is a timing function. It maps the progress of an animation (0 to 1) to its visual output over time. A linear curve moves at constant speed. A cubic bezier can accelerate, decelerate, overshoot, or bounce. The same 300ms animation feels completely different depending on the curve driving it.
Yet in most codebases, you'll find one or two easing values copy-pasted everywhere: ease-in-out, maybe a cubic-bezier(0.4, 0, 0.2, 1) if someone read the Material spec. This is like setting your entire app in one font weight. It works, but it says nothing.
The thesis: Easing curves carry semantic meaning. Different interaction contexts demand different curves, and the right curve makes motion feel intentional while the wrong one makes it feel like a tech demo.
See the difference, feel the difference
These four balls travel the same distance in the same duration. The only variable is the easing curve. Hit play and watch how dramatically the character changes:
Easing racetrack — 800ms, same distance
Same duration, same distance, wildly different personality
Linear feels mechanical, robotic. Useful for progress indicators where you want to communicate constant, predictable progress. Ease-out feels responsive and natural, the element rushes to respond then settles. Spring feels alive, organic, it overshoots slightly like a physical object. Bounce is playful but distracting, perfect for a game, terrible for a banking app.
Each curve is a tone of voice. And just like you wouldn't write error messages in Comic Sans, you shouldn't animate a delete confirmation with a bouncy spring.
A vocabulary of curves
Here's a practical taxonomy. Not every curve in existence, but the ones that cover 95% of interface motion. Hover each card to see the curve in action:
Curve personalities
Ease-out
cubic-bezier(0, 0, 0.2, 1)
The workhorse. Fast start, gentle landing. Use for responses to user input.
Ease-in
cubic-bezier(0.4, 0, 1, 1)
Slow start, fast finish. For exits and dismissals.
Spring
stiffness: 300, damping: 24
Overshoots and settles. Feels physical. Great for modals and popovers.
Sharp ease
cubic-bezier(0.12, 0, 0.08, 1)
Near-instant with a subtle tail. For toggles, checkboxes, tab switches.
Hover cards to preview each curve's motion character
The asymmetry rule: Entrances and exits should never use the same curve. Entrances ease-out (fast-in, slow-out). Exits ease-in (slow-in, fast-out). This mirrors how physical objects move. They don't symmetrically reverse their arrival.
The curve playground
Pick a preset to see the curve shape and preview its motion. Notice how the graph's shape directly maps to the ball's behavior. Steep sections mean fast movement, flat sections mean slow:
Bezier curve visualizer
Select presets to compare curve shapes and motion feel
/**
* Easing tokens — a semantic motion system.
* Name by intent, not by shape.
*/
export const motion = {
respond: "cubic-bezier(0, 0, 0.2, 1)",
enter: "cubic-bezier(0, 0, 0.2, 1)",
exit: "cubic-bezier(0.4, 0, 1, 1)",
announce: "cubic-bezier(0.34, 1.56, 0.64, 1)",
snap: "cubic-bezier(0.12, 0, 0.08, 1)",
fast: "150ms",
normal: "250ms",
slow: "400ms",
dramatic: "600ms",
} as const
Context-dependent motion
The right curve depends entirely on the interaction context. Click each row to see the motion that matches:
Context → curve mapping
Click each row to see the matching motion
Building a motion system
The practical takeaway is to stop thinking about easing curves as a single value and start thinking about them as a vocabulary.
1. Name curves by intent, not shape
Don't call it easeOutQuint in your tokens. Call it motion.respond or motion.enter. When a new developer joins, motion.snap tells them something that cubic-bezier(0.12, 0, 0.08, 1) never will.
2. Pair curves with durations
A sharp ease at 600ms feels sluggish. A spring at 100ms doesn't have time to bounce. Curves and durations are inseparable. Micro-interactions: 100-200ms. Standard transitions: 200-350ms. Dramatic entrances: 350-600ms. Anything over 600ms had better have a very good reason.
3. The 60/30/10 rule of motion
60% of your animations should use your workhorse ease-out. It's the body text of motion. Reliable, invisible, correct. 30% should use your secondary curves (snap for micro-interactions, ease-in for exits). 10% can be dramatic: springs, overshoots, custom curves. This ratio keeps the UI feeling calm while reserving expressiveness for moments that deserve attention.
4. Spring physics for the top 10%
For your most important animations (modals opening, toast notifications, drag-and-drop settling) consider spring physics instead of bezier curves. Springs respond to velocity, feel connected to the user's gesture, and never look mathematically canned. Framer Motion makes this trivial with type: "spring".
A test: Mute the motion in your app by setting all durations to 0. If the app feels broken, if you lose hierarchy, feedback, or spatial orientation, your motion is load-bearing, and it deserves the same design rigor as your type system. If nothing changes, you're decorating, not designing.
The silent language
Easing curves are the typographic weights of motion. ease-out is your regular weight, the default, the workhorse. spring is bold, attention-grabbing, used sparingly. linear is monospace, technical, mechanical, specific. ease-in is light, receding, departing, diminishing.
When you treat motion as a language rather than a decoration, something shifts. Animations stop being "nice to have" and start being structural. They communicate hierarchy, causality, spatial relationships, and emotional tone. The curve isn't an implementation detail. It's a design decision.
The next time you type transition: all 0.3s ease, pause. Ask: what is this animation trying to say? Is it responding to user input? Announcing something new? Dismissing something finished? The answer tells you the curve. And the curve tells the user everything they need to feel, without reading a single word.