Custom CSS Cubic-Bezier Curve Generator
Drag the two handles, type exact coordinates, or pick from a full easing library — then play it back next to a linear comparison so you can actually feel the difference, on movement, scale, rotation, or fade.
What the four cubic-bezier numbers mean
cubic-bezier(x1, y1, x2, y2) plots two control points against a time (x) and progress (y) axis. Y values above 1 or below 0 make the animation briefly overshoot or undershoot before settling — that's what produces a back-out anticipation effect. Type exact coordinates into the number fields for pixel-precise curves, or drag the handles freehand.
Using a custom transition easing tool
Paste the generated cubic-bezier() into any transition or animation-timing-function property, or switch the copy format to a plain JS array for animation libraries that take raw coordinates. Turn on "compare with linear" before hitting play to see exactly how much character your curve adds over no easing at all — try it against move, scale, rotate, and fade, since the same curve can feel different depending on what it's applied to.
Worked example: the default curve is the CSS keyword ease
The generator opens on control points 0.25, 0.10, 0.25, 1.00 with a 0.6s duration, and writes:
.eased-element {
transition: 0.6s cubic-bezier(0.25, 0.10, 0.25, 1.00);
}
/* or as a reusable timing function */
animation-timing-function: cubic-bezier(0.25, 0.10, 0.25, 1.00);
Those four numbers are exactly the curve the browser uses for the keyword ease, which is also the default timing function, so this starting curve behaves the same as writing no easing at all. Every other built-in keyword is just another set of four numbers, listed below.
The two x values must stay between 0 and 1, but the y values can go outside that range. A y above 1 makes the animation overshoot its target and settle back, which is how bounce-style easings are made. For example, cubic-bezier(0.34, 1.56, 0.64, 1) overshoots slightly before landing.
Built-in keywords and their curves
| Keyword | Equivalent cubic-bezier() |
|---|---|
| linear | cubic-bezier(0, 0, 1, 1) |
| ease | cubic-bezier(0.25, 0.1, 0.25, 1) |
| 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) |
Frequently asked questions
What do the four numbers in cubic-bezier() mean?
They're the x and y coordinates of two control points that shape the easing curve between 0 and 1. The x values control timing (must stay within 0-1), while y values control the 'overshoot' or intensity of the motion and can go outside that range.
What's the difference between ease-in-out and a custom cubic-bezier?
ease-in-out is itself just a preset cubic-bezier curve — cubic-bezier(0.42, 0, 0.58, 1). Writing your own control points lets you create effects the built-in keywords can't, like a pronounced overshoot or a snappy anticipation before the main motion.
Why does my animation look like it 'pops' at the very start or end?
That usually means one of your y control points is set far outside the 0-1 range, causing the curve to shoot past its target before settling — sometimes intentional for a bouncy effect, but worth flattening back toward 0-1 if it looks like a glitch instead.
Can I use the same easing curve for both CSS transitions and animations?
Yes — cubic-bezier() values work identically in the transition-timing-function and animation-timing-function properties, so a curve you like for a hover effect can be reused directly in a keyframe animation.