Cubic Bezier Generator
Developer Tools · Added
Every CSS easing keyword is a cubic Bézier curve underneath, and writing your own is how an animation stops feeling generic. The curve maps elapsed time on the horizontal axis to progress on the vertical, so a steep section means fast movement and a flat one means the property has almost stopped. This builds the curve, draws it with its control handles, tabulates what it computes to at each moment, and handles overshoot — the springy motion you get when the curve deliberately goes past its target.
Result
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);starts slowly, settles gently.
- Equivalent keyword
- None
- Peak progress
- 100.0%
- Lowest progress
- 0.0%
A custom curve
Settles without overshoot
Moves forward throughout
Progress through the animation
| Time elapsed | Progress |
|---|---|
| 0% | 0.0% |
| 20% | 13.4% |
| 40% | 61.4% |
| 60% | 87.6% |
| 80% | 97.5% |
| 100% | 100.0% |
The horizontal axis is time and the vertical is progress, so a steep section means fast movement and a flat one means the property has almost stopped changing. The dashed lines are the control handles — dragging the first towards the right delays the start, and pulling the second one down makes the finish gentler. A y value above 1 produces overshoot, which is what makes a motion feel springy; below 0 gives anticipation, a small pull-back before the move.
How to use the cubic bezier generator
- 1Set the four numbers, or start from a keyword or preset and adjust.
- 2The x values must stay between 0 and 1 — they are positions in time, and CSS rejects anything outside.
- 3The y values may go below 0 or above 1, which is what produces anticipation and overshoot.
- 4Read the curve: the dashed lines are the control handles, and the shaded band is the 0 to 100% progress range.
- 5Copy the declaration, or paste an existing cubic-bezier value into the import box to load and tweak it.
Examples
The workhorse ease-out
- Input
- 0.4, 0, 0.2, 1
- Result
- Fast start, gentle settle — 68% complete at the halfway point
The standard curve in most design systems, and the right default for anything arriving on screen.
An overshoot
- Input
- 0.34, 1.56, 0.64, 1
- Result
- Reaches 110% before settling back to 100%
The y value above 1 is what takes it past the target. Legal CSS, and easy to overuse.
An anticipation
- Input
- 0.68, -0.55, 0.27, 1.55
- Result
- Pulls back below 0% first, then overshoots
A cartoon wind-up. Both extremes are outside the 0-1 band, which is why the plot expands to show them.
About the cubic bezier generator
Reading the curve
The horizontal axis is elapsed time, from the start of the animation to the end, and the vertical axis is how far the property has moved from its old value to its new one. A straight diagonal is constant speed. A curve that rises steeply at first and flattens is fast then slow; one that starts flat and rises steeply at the end is the reverse.
The two control points are what shape it, and their effect is fairly intuitive once seen. Dragging the first point to the right delays the start, because the curve hugs the horizontal axis for longer. Pulling the second point down and left makes the ending gentler, because the curve approaches its final value more gradually. The curve never passes through the control points themselves — it is pulled towards them, which is what the dashed handles in the plot illustrate.
The tabulated progress underneath is the part worth checking against intuition. A curve that looks reasonable can still be doing something surprising in the middle, and seeing that it is 68% complete at the halfway mark tells you more about how the motion will feel than the shape alone does.
Duration, easing and the thing people actually notice
Easing decides how a motion feels; duration decides whether anybody enjoys it. The two are commonly confused, and the more frequent mistake by far is duration — an animation that is beautifully eased and takes 800 milliseconds is simply slow, and slowness on an interface element that a user triggers dozens of times a day is an irritation regardless of the curve.
The rough figures that hold up in practice: 150 to 200 milliseconds for a small element changing state, 250 to 300 for something moving across a card or panel, and 300 to 400 for a full-screen transition. Larger distances warrant longer durations, which is the one piece of real physics in the whole business — a bigger object moving further genuinely does take longer.
The other consideration is that not everybody wants motion at all. The `prefers-reduced-motion` media query exists because vestibular disorders make large animated movement genuinely unpleasant, and honouring it costs one media query that sets durations to near zero. A carefully tuned curve is worth nothing to somebody who has asked the browser not to animate, and shipping without that check is the most common accessibility failure in animation work.
Frequently asked questions
Why must the x values stay between 0 and 1?
How is the progress at a given time actually calculated?
Which curve should I use for what?
Are the CSS keywords anything special?
Can I use these for anything other than transitions?
Related tools
CSS Clamp Generator
Developer Tools
Build a fluid clamp() that scales a size between two viewport widths.
Border Radius Generator
Developer Tools
Round corners individually, including the elliptical eight-value form.
CSS Gradient Generator
Developer Tools
Build a linear, radial or conic CSS gradient visually and copy the declaration.