All tools

Cubic Bezier Playground

Build CSS easing curves visually — drag two control points, preview the animation, copy the cubic-bezier(...) string.

  • cubic-bezier
  • css
  • animation
  • easing
  • transition
  • curve
  • timing-function

About Cubic Bezier Playground

CSS animations and transitions use a timing function to decide how a property's value changes over the duration — not just "linear from start to finish" but accelerating, decelerating, overshooting, or any custom shape. cubic-bezier() is the most flexible built-in: it takes four numbers defining two control points (P1.x, P1.y, P2.x, P2.y) of a cubic Bezier curve from (0,0) to (1,1), and the curve's y at each x is the eased progress at that point in time.

The x coordinates are clamped to [0, 1] but the y coordinates can be anything — values above 1 or below 0 produce overshoots and bounces. The familiar keyword easings (ease, ease-in, ease-out, ease-in-out) are all specific cubic-bezier curves; this tool starts from any of them and lets you tweak the handles by dragging.

How to use

Drag the two control points on the canvas. P1 (top-left) controls the start of the curve, P2 (bottom-right) controls the end. The y axis is inverted on screen so the curve goes up-and-right like a graph; the values shown below match the CSS coordinate system.

Click "Play" to trigger the preview animation — a square moves left-to-right using your easing. Use the preset buttons to jump to a named curve, then nudge the handles. The "Copy CSS" button copies the full cubic-bezier(x1, y1, x2, y2) declaration. The URL updates with your handle positions so you can share or bookmark a specific curve.

Frequently asked questions

  • What do the four numbers in cubic-bezier(x1, y1, x2, y2) mean?

    They're the coordinates of two control points on a cubic Bezier curve from (0,0) to (1,1). (x1, y1) is the first control point — the tangent direction the curve leaves the start with. (x2, y2) is the second control point — the tangent direction the curve approaches the end with. The x values are clamped to [0, 1] but the y values are unbounded, so y > 1 or y < 0 produces overshoots.

  • What are the keyword easings actually equal to?

    linear is cubic-bezier(0, 0, 1, 1). ease is cubic-bezier(0.25, 0.1, 0.25, 1) — a soft acceleration-then-deceleration that's the default for CSS transitions. ease-in is cubic-bezier(0.42, 0, 1, 1) — slow start, fast end. ease-out is cubic-bezier(0, 0, 0.58, 1) — fast start, slow end. ease-in-out is cubic-bezier(0.42, 0, 0.58, 1) — slow at both ends, quick through the middle.

  • How do I make an overshoot or bounce?

    Push the y coordinate of either control point above 1 (for an overshoot at the end) or below 0 (for an undershoot at the start). A classic "back" easing is roughly cubic-bezier(0.68, -0.55, 0.27, 1.55), which dips below the start before rising past the end. Full bouncing animations with multiple oscillations can't be done with a single cubic-bezier — you'd need a CSS keyframe animation or the steps()/linear() timing functions.

  • What about ease-in-out vs ease-out-in?

    ease-in-out exists as a keyword and is the conventional "slow at both ends" shape. There's no ease-out-in keyword, but the curve does exist conceptually — it would be fast at both ends and slow through the middle, which feels mechanical and is rarely useful. You can build it with cubic-bezier(0, 0.5, 1, 0.5) if you want to try.

  • Should I use cubic-bezier or the newer linear() function?

    cubic-bezier handles smooth curves with a single inflection — most easings you'd want. linear() (available in modern browsers since 2023) accepts an arbitrary list of stops and is what you reach for when you need multi-bounce springs, custom keyframe-driven curves, or to replicate JavaScript easing libraries exactly. For typical "ease this transition" cases, cubic-bezier is shorter, more readable, and universally supported.

More Web & Dev tools