Cubic Bezier Editor

How to use 3 steps
  1. Pick a Preset, or set P1 and P2 yourself.
  2. Press Replay to watch the motion at your chosen duration.
  3. Press Copy CSS and paste it into your stylesheet.
Generated CSS

The vertical axis runs past 0 and 1 on purpose: control points outside that range are what produce overshoot and anticipation. The horizontal axis cannot, because a curve whose x leaves 0–1 is not a function of time and browsers reject it. The moving square uses the same curve the CSS below describes, so what you see is what ships.

How this tool works

A timing function does not describe where something moves; it describes how the animation's progress maps onto time. The curve runs from nought to one on both axes, the horizontal being elapsed time and the vertical being how far through the change the element is. A straight diagonal is a linear animation. The bend is what makes movement read as natural, because nothing in the physical world starts and stops at a constant rate.

Four numbers set the two control points, and the curve is drawn as an SVG path alongside a ball that replays the motion whenever a value changes. Replaying it needs a forced reflow between resetting the transition and setting the new one, otherwise the browser coalesces both writes and nothing appears to happen. The output is offered as a transition and as an animation, since the same function is used by both.

Reading the curve and choosing a shape

  • Steepness is speed: where the curve rises sharply the element is moving fast; where it flattens the element has almost stopped. A long flat tail is the commonest reason an animation feels sluggish at the end.
  • The vertical axis may leave the nought-to-one range: values above one overshoot the target and come back, which is what makes a bounce. The horizontal axis cannot, because time does not run backwards.
  • Ease-out suits things arriving, ease-in suits things leaving: an element entering the screen should decelerate into place; one being dismissed can accelerate away, because nobody is waiting to look at it.
  • Duration and curve are judged together: a pronounced curve at a long duration reads as slow rather than as characterful. Most interface motion sits between 150 and 300 milliseconds.

The curve is not the path

The commonest misreading of an easing curve is that it shows where something moves. It does not. It maps the animation's progress onto time.

Elapsed time runs along the bottom, from nought to one. How far through the change the element is runs up the side, also nought to one. A straight diagonal means the element moves at a constant rate for the whole duration. The bend is what makes movement read as natural, because nothing in the physical world starts and stops instantly.

Steepness is speed. Where the curve rises sharply, the element is moving fast; where it flattens, it has almost stopped. The [msm_tool slug="cubic-bezier-editor"] replays the motion beside the curve, which is the fastest way to connect the two.

Reading a curve at a glance

  • Steep at the start, flat at the end. The element launches and settles — this is ease-out, and it is what most things arriving on screen should do.
  • Flat at the start, steep at the end. Ease-in: a slow build then a rush. Right for things leaving, wrong for things arriving, because the user waits through the slow part.
  • Flat at both ends. Ease-in-out. Smooth but slightly lifeless for short interface movements; better suited to longer transitions between states.
  • A long flat tail. The commonest fault. The last part of the movement crawls, and the animation feels sluggish however short its total duration.

Arriving and leaving are different

An element entering the screen should decelerate into place. The user is about to look at it, and it should be still by the time their attention arrives.

An element being dismissed can accelerate away, because nobody is waiting to look at it. That asymmetry — ease-out coming in, ease-in going out — is one of the few motion rules that holds almost everywhere, and it costs nothing to apply.

Overshoot

The vertical axis may go above one, and that is what produces a bounce: the element passes its target and comes back. Push the second control point's vertical value past one to get it.

The horizontal axis cannot leave the nought-to-one range, because time does not run backwards. A curve that tries produces a shape the browser will not accept.

Overshoot is effective and easy to overdo. A small one — a few percent past the target — reads as physical. A large one reads as a toy, and on anything a person uses repeatedly it becomes tiring within a day.

Duration and curve are judged together

A pronounced curve at a long duration reads as slow rather than as characterful. Most interface motion sits between 150 and 300 milliseconds; below about 100 it is not perceived as motion at all, and above roughly 400 people start waiting.

Larger movements need slightly longer than small ones to feel like they travelled rather than teleported. A full-screen panel sliding in can take 300; a button changing colour should not.

The named keywords, and when they are enough

CSS ships with ease, ease-in, ease-out, ease-in-out and linear. Each is a cubic Bézier with fixed control points, and for a great deal of interface work they are entirely sufficient.

ease is the default and is a reasonable general choice. linear is usually wrong for movement — it is the one thing that never happens in the physical world — with one exception: continuous rotation, such as a loading spinner, where any easing produces a visible stutter each time round.

A custom curve earns its place when you want a specific character: a snappy launch, a gentle settle, an overshoot. If you cannot say what you want in those terms, a keyword will do.

Transitions and keyframes use it differently

On a transition, the curve applies across the whole change. On a keyframe animation, it applies between each pair of keyframes rather than across the sequence.

That catches people out: adding an ease to a three-keyframe animation eases three separate times, producing a stutter at each keyframe rather than one smooth arc. If you want a single curve across the whole thing, use two keyframes and let the curve do the shaping.

Respect reduced motion

Whatever curve you choose, wrap the animation in a check for the reader's motion preference. Vestibular disorders make large or repeated movement genuinely unpleasant, and honouring the system setting costs three lines:

@media (prefers-reduced-motion: reduce) { .thing { transition: none; } }

The setting exists because people asked for it. Overriding it because the animation is tasteful is not a judgement call anyone else has delegated to you.

Frequently Asked Questions

Specific to the Cubic Bezier Editor. Broader questions about this category are answered on the category page.

They are the two control points of the curve, as x and y pairs. The first pulls the start of the animation, the second pulls the end.
Push the second control point's vertical value above one. Time cannot exceed its range, but progress can, and that is what produces the bounce.
Look at the end of the curve. A long flat tail means the last part of the movement crawls, which reads as sluggish however brief the total time.
Ease-out for something arriving, so it decelerates into place. Ease-in for something leaving, since nobody is waiting to look at it.
Yes, and both forms are generated. A keyframe animation applies the curve between each pair of keyframes rather than across the whole sequence.

Subscribe to receive notifications about new tools, features, and productivity tips.