Skip to content
ToolBoxGeniehome

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.

Must be between 0 and 1

May go outside 0 and 1 for overshoot

Must be between 0 and 1

May go outside 0 and 1

Press Import to load it into the fields above

CSS keywords:
Presets:

Result

transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);

starts slowly, settles gently.

Equivalent keyword
None

A custom curve

Peak progress
100.0%

Settles without overshoot

Lowest progress
0.0%

Moves forward throughout

Progress through the animation

Time elapsedProgress
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

  1. 1Set the four numbers, or start from a keyword or preset and adjust.
  2. 2The x values must stay between 0 and 1 — they are positions in time, and CSS rejects anything outside.
  3. 3The y values may go below 0 or above 1, which is what produces anticipation and overshoot.
  4. 4Read the curve: the dashed lines are the control handles, and the shaded band is the 0 to 100% progress range.
  5. 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?
Because they are positions in time, and a control point outside that range would make the animation run backwards partway through. The CSS specification requires it, and browsers do not clamp the value — they reject the whole declaration as invalid, so the element falls back to whatever timing function it had before. The y values carry no such restriction, since progress genuinely can go past the target and come back.
How is the progress at a given time actually calculated?
Not directly, because the curve is parametric: both x and y are functions of a parameter t, and t is not time. Finding the progress at 40% of the duration means first solving x(t) = 0.4 for t, then evaluating y at that t. There is no practical closed form for the solve, so browsers use Newton-Raphson from a good initial guess and fall back to bisection where the derivative is too small — which is exactly what this page does, so the numbers match what ships.
Which curve should I use for what?
As a rule, ease-out for things arriving and ease-in for things leaving. Something entering the screen should decelerate into place, which reads as arriving under control; something exiting should accelerate away, which reads as departing. Movement between two visible positions suits a symmetric ease-in-out. Linear is worth avoiding for anything spatial — nothing in the physical world starts and stops instantly, so it reads as mechanical.
Are the CSS keywords anything special?
No, they are just named curves. `ease` is cubic-bezier(0.25, 0.1, 0.25, 1), `ease-in` is (0.42, 0, 1, 1), `ease-out` is (0, 0, 0.58, 1) and `ease-in-out` is (0.42, 0, 0.58, 1). `linear` is the straight line from corner to corner. This page names the keyword when your curve happens to match one exactly, which is a useful check that a hand-tuned curve has not accidentally reinvented the default.
Can I use these for anything other than transitions?
Yes — the same value works in `animation-timing-function`, in the `easing` option of the Web Animations API, and in most JavaScript animation libraries, which take the four numbers directly. It is also worth knowing what a Bézier curve cannot express: genuine spring physics, which continues oscillating for a variable time depending on where it started. CSS has `linear()` with sampled points for that, and dedicated spring libraries do it properly.