Skip to content

Cubic Bezier Generator

Shape a custom CSS easing curve with four control values, see the curve and a live animation, and copy the cubic-bezier() rule.

Runs in your browserFree, no sign-up

Settings

Pick a preset to load its control values, then fine-tune them below.

Results update automatically as you type.

Curve and live animation

CSS

.element {
  transition-property: transform;
  transition-duration: 1.4s;
  transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
}

/* Shorthand */
.element {
  transition: transform 1.4s cubic-bezier(0.25, 0.1, 0.25, 1);
}

Values

Timing function
cubic-bezier(0.25, 0.1, 0.25, 1)
Control point 1
0.25, 0.1
Control point 2
0.25, 1
Character
Stays within range

Why use Cubic Bezier Generator

Every CSS transition follows a curve that decides how the change is distributed across its duration, and cubic-bezier() is how you write your own instead of settling for the handful of built-in keywords. Adjust the two control points and you can see both the curve itself and a live animation driven by it, which matters because a curve that looks reasonable on a graph can still feel wrong in motion. The presets cover the standard keywords plus two curves the keywords cannot express — an overshoot that springs past the target before settling, and an anticipation that pulls back slightly before moving forward.

What the four numbers actually control

A cubic bezier is defined by four points, but two of them are fixed: the curve always starts at (0,0) and ends at (1,1). The four numbers you write are the coordinates of the two control points in between, in the order x1, y1, x2, y2. The horizontal axis is time — how far through the duration you are — and the vertical axis is progress, how much of the change has been applied. This is why the axes are not interchangeable and why x is constrained to the range 0 to 1 while y is not: time cannot run backwards or extend past the duration, but the animated value can perfectly well overshoot its target and come back. Reading a curve becomes intuitive once you internalise that a steep section means fast movement and a flat section means the value is barely changing. A curve that is flat at the start and steep at the end is the classic ease-in: nothing much happens, then everything happens at once.

Choosing curves that feel right rather than look right

The most useful rule in interface motion is that things entering the screen and things leaving it want different curves. An element appearing should decelerate into place — fast at first, slowing as it arrives — which is an ease-out and reads as responsive because the movement begins the instant the user acts. An element leaving should accelerate away, an ease-in, because nobody needs to watch it depart carefully. Applying a symmetrical ease-in-out to both is the most common mistake and is what makes an interface feel slightly sluggish even at a short duration, since it spends the opening frames barely moving. Duration interacts with this: the more dramatic the curve, the shorter it should run, because an aggressive overshoot at 600ms reads as a glitch while the same curve at 200ms reads as liveliness. It is also worth pairing any decorative motion with a prefers-reduced-motion query, since overshoot and bounce are precisely the effects that trigger discomfort for motion-sensitive users.

Step by step

  1. 1

    Pick a preset to start from, or leave it on Custom to shape the curve entirely with the sliders.

  2. 2

    Drag the P1 sliders to control how the animation starts, and the P2 sliders to control how it ends.

  3. 3

    Set a duration and watch the live animation — motion tells you far more than the curve shape alone.

  4. 4

    Copy the generated CSS, which includes both the longhand properties and the transition shorthand.

Where this helps

Making UI transitions feel deliberate

A menu that eases out quickly and settles gently reads as responsive, while a linear transition of the same duration feels mechanical.

Adding a spring without a JavaScript library

A y value above 1 overshoots and settles back, which gives buttons and modals a bounce that costs nothing beyond a single CSS property.

Matching a design system's motion spec

Design tools export easing as four bezier values. Pasting them here confirms the curve behaves the way the spec intends before it ships.

Debugging an animation that feels wrong

When motion feels sluggish despite a short duration, the curve is usually the cause — a slow start eats most of the time before anything visibly moves.

Worth knowing

  • Use ease-out for entrances and ease-in for exits; symmetrical curves are rarely the right choice for either.
  • Keep interface transitions between 150ms and 300ms — long enough to read as motion, short enough not to make people wait.
  • Wrap expressive curves in a prefers-reduced-motion media query so users who ask for less movement are not subjected to bounce effects.

Frequently asked questions

What do the four numbers in cubic-bezier() mean?
They are the x and y coordinates of two control points: cubic-bezier(x1, y1, x2, y2). The start point (0,0) and end point (1,1) are fixed. X is progress through the duration and Y is progress through the change, so dragging a control point upward makes that part of the animation move faster.
Can the y values go above 1 or below 0?
Yes, and that is how you get bounce-like motion. A y value above 1 overshoots the final value before settling, and a value below 0 pulls backwards before moving forward. X values must stay between 0 and 1, because time cannot run backwards.
How does this relate to ease, ease-in and ease-out?
Those keywords are aliases for specific curves — ease is cubic-bezier(0.25, 0.1, 0.25, 1) and ease-in is cubic-bezier(0.42, 0, 1, 1). Writing the curve yourself simply gives you the values in between them.
Does the easing curve work for CSS animations as well as transitions?
Yes. The same value goes in animation-timing-function, and it applies between keyframes rather than across a single state change.

Looking for something else? Browse all css tools or see every tool.