Skip to content

How to shape a cubic-bezier() curve and copy the CSS declaration

The editor turns four control points — x1, y1, x2, y2 — into a cubic-bezier() easing function, draws the resulting timing curve and replays a real CSS transition with it. The curve, the code and the preview are built inside the page: the function is assembled locally and no value is uploaded.

x1 and x2 stay inside 0–1, which is what the CSS grammar requires, while y1 and y2 accept −2–2 so overshoot curves are possible. The canvas plots the usual −0.5–1.5 window and widens when a control point is pushed beyond it, so a point never leaves the drawing.

  1. Choose a preset — ease, linear, ease-in, ease-out, ease-in-out or overshoot — or drag P1 and P2 on the canvas. A drag only starts when the pointer lands on a handle, so clicking elsewhere on the plot does not move a point.
  2. For exact numbers type x1, y1, x2 and y2. The fields accept decimals and negative values, and each entry is rounded to two decimals and clamped into its range (x: 0–1, y: −2–2) when you press Enter or leave the field.
  3. Set Duration, 100–5000 ms. It is the value written into the copied CSS and the time the replay dot takes to cross the track.
  4. Press Replay animation to run the dot with the current curve. The dot uses a real CSS transition, so it shows the browser’s own interpolation instead of a drawn approximation.
  5. Copy CSS puts the generated rule on the clipboard; Reset restores the defaults x1 0.25, y1 0.1, x2 0.25, y2 1 and 900 ms.

Control points, the timing canvas and the generated transition

What the copied CSS contains

The block is one rule — .animated-element { transition: transform <duration>ms cubic-bezier(x1, y1, x2, y2); } — so the selector and the animated property are placeholders you replace with your own; the timing function is the part this editor produces. The four numbers are rounded to two decimals, exactly as they appear in the code panel.

The code panel, the easing applied to the replay dot and the drawing of the curve all read the same four fields, so the preview cannot drift away from the declaration you copy.

How the curve canvas is laid out

The x axis runs 0–1 across the plot and the y axis shows the timing window; vertical grid lines mark quarters of x and horizontal lines every 0.5 of y inside the visible range. The two control points are drawn at their coordinates and the curve is the cubic through (0,0), the two handles and (1,1).

The visible y window is −0.5 to 1.5 by default. If a control point goes beyond it — the overshoot preset puts y1 at 1.56 and the fields accept up to 2 — the window stretches just far enough to keep the handle and its curve segment on the canvas instead of clipping them.

Limits, defaults and local processing

x values are clamped to 0–1 and y values to −2–2, the duration to 100–5000 ms, and values are rounded to two decimals. The preset selector switches to a Custom entry as soon as a value is edited by hand or by dragging, so the menu never claims a curve the fields no longer hold.

Nothing is uploaded: after the page had loaded, choosing presets, dragging, typing, replaying, copying and resetting sent no network request at all in the en, fr and ja probe runs. The preview uses the browser’s own CSS transition implementation, which is also why the page keeps working offline.

Recent tools: