Cubic Bezier Generator
Visual editor for CSS cubic-bezier() easing curves. Drag the control handles, see the live animation, copy the CSS. Free, in-browser.
cubic-bezier(0.42, 0.00, 0.58, 1.00)transition-timing-function: cubic-bezier(0.42, 0.00, 0.58, 1.00);What this does
Visual editor for CSS cubic-bezier() timing functions. Drag the two purple/pink handles to shape the curve. The CSS expression updates live, and a circle animates with the current curve so you can feel how it actually moves before committing.
Reading a cubic-bezier curve
The X axis is time (0 = animation start, 1 = animation end). The Y axis is progress (0 = no movement, 1 = fully moved). Both axes are normalized 0–1.
A straight diagonal from corner to corner is linear — equal progress per equal time. The classic ease curves bow above the diagonal: at 50% time, you’re already past 50% progress (fast start, slow end), or below the diagonal (slow start, fast end), or both at different points.
Y values can go below 0 or above 1. That’s how you build “overshoot” (bounces past the target then settles back) and “anticipate” (pulls back before launching forward) effects.
What the four control points mean
cubic-bezier(p1x, p1y, p2x, p2y)
p1 is the first control point — it pulls the curve in the direction the animation should leave the start. The closer p1 is to (0, 0), the slower it leaves.
p2 is the second control point — it pulls the curve in the direction the animation should approach the end. The closer p2 is to (1, 1), the slower it lands.
X values are clamped to 0–1 in this editor (mathematically valid bezier curves require this for time monotonicity). Y values are unbounded.
CSS keyword equivalents
The four CSS keywords map to specific cubic-bezier values:
| Keyword | Equivalent | What it feels like |
|---|---|---|
linear | cubic-bezier(0, 0, 1, 1) | Robotic, no acceleration |
ease | cubic-bezier(0.25, 0.1, 0.25, 1.0) | Default. Subtle ease-out feel. |
ease-in | cubic-bezier(0.42, 0, 1.0, 1.0) | Slow start, full-speed finish |
ease-out | cubic-bezier(0, 0, 0.58, 1.0) | Full-speed start, gentle finish |
ease-in-out | cubic-bezier(0.42, 0, 0.58, 1.0) | Slow at both ends |
When to use what
ease-outis the default for most UI motion. Things appear at full speed and decelerate. Feels natural — matches how physical objects come to rest.ease-inis for things leaving the screen. Their start should be gentle, their exit fast.ease-in-outfor symmetric movements like a panel sliding open and closed.- Overshoot for playful UI — a card “lands” past its target then settles. Good for important success states. Avoid for routine transitions.
- Linear for continuous motion — progress bars, infinite carousels, anything where deceleration would feel wrong.
Common mistakes
- Too long a duration. A 1-second easing for a button hover is sluggish. UI motion lives in 150–300ms territory. Marketing animation sometimes goes longer (500–800ms). Anything over 1 second on routine UI feels broken.
- Using
ease-inwhereease-outbelongs. New content sliding in withease-inaccelerates as it appears — it feels off-balance because you don’t track its arrival. Useease-outso it appears fast then settles. - Same curve everywhere. Reuse the same easing across a single component (panel-open and panel-close should share a curve), but vary across components — different motion personalities for different flows.
CSS shorthand
The curve goes in transition-timing-function, animation-timing-function, or as the third argument to the transition shorthand:
.btn { transition: opacity 200ms cubic-bezier(0.42, 0, 0.58, 1.0); }
In Web Animations API:
el.animate([{opacity:0},{opacity:1}], {duration:200, easing:'cubic-bezier(0.42,0,0.58,1)'});
Privacy
Runs entirely in your browser.