Skip to content

Cubic Bezier Editor

Drag handles, pick from 30 named easings, or paste any CSS easing. Live preview of motion, scale, and rotation. Elastic and bounce auto-export as linear(). For physics-based motion instead, try the Spring Visualizer.Drag handles, preview motion, copy the exact easing.

Use arrow keys to move the selected bezier handle by 0.1. Hold Shift for 0.01. Hold Alt to snap to the grid.

transition: transform 500ms cubic-bezier(.25, .1, .25, 1)
x1
y1
x2
y2
Duration
ms
In
Out
InOut
Sine
Quad
Cubic
Quart
Quint
Expo
Circ
Back

Why this exists

Easing is hard to judge from the four numbers in cubic-bezier(). This editor lets you drag the curve, watch it move, and copy the exact value into your app – instead of guessing coordinates and reloading to check.

Coding agents build UI fast, but they tend to reach for ease-in-out or guess a curve. Hand one a precise cubic-bezier(), or paste it into the prompt, and the motion is intentional rather than a default.

Who it is for

Product designers, prototypers, and frontend developers tuning CSS transitions – and anyone building UI with coding agents.

How to use it

Drag the two handles or pick a named preset, set the duration, watch the preview, then copy the code for your framework.

What the controls do

  • Handles – bend the curve. X stays within 0–1; Y can overshoot for back/anticipate motion.
  • Presets – 30 named Penner easings, one click; elastic and bounce export as linear().
  • Paste – drop in any CSS easing or four numbers to edit it.
  • Duration – the transition time the preview and exports use.

Handing it off

Do not hand off “make it snappier”. Hand off the curve, the preview, and the exact cubic-bezier() / linear(). Copy once, keep motion consistent across platforms.

How cubic-bezier easing works

Every CSS easing curve is defined by two control handles in a unit square. The curve starts at (0, 0), ends at (1, 1), and your two handles bend the path between them. The four numbers in cubic-bezier(x1, y1, x2, y2) are just the coordinates of those handles.

The 24 named easings – Sine, Quad, Cubic, Quart, Quint, Expo, Circ, Back – are all derived from Robert Penner's equations, which approximate polynomial and trigonometric easing as four-number cubic-beziers. Back curves overshoot above 1 or below 0, which is allowed for y but not for x – that's a CSS spec rule the editor enforces.

Elastic and bounce easings oscillate, so a single cubic-bezier can't represent them. The editor stores those six presets as linear() functions – sampled point lists from Penner's actual oscillating formulas. linear() is a CSS Easing Level 2 feature supported in all modern browsers since 2023.

For everything else, use Framer Motion's spring system instead – physics-based motion with mass, stiffness, and damping. The Spring Visualizer handles that.

Frequently asked questions

What is a cubic-bezier easing curve?

A cubic-bezier easing is a CSS timing function defined by four numbers: cubic-bezier(x1, y1, x2, y2). It controls how a value changes over time using a smooth curve with two adjustable handles. The four numbers position those handles. CSS transitions and animations use cubic-bezier to give motion a personality – ease-in, ease-out, snappy, lazy, springy.

Why do some presets use linear() instead of cubic-bezier()?

Cubic-bezier curves are monotonic – they go from 0 to 1 along a single smooth path. Elastic and bounce easings oscillate and overshoot, which a single cubic-bezier cannot represent. CSS Easing Level 2 introduced the linear() function (Chrome 113+, Firefox 112+, Safari 17.4+), which accepts a list of sample points and can approximate any curve. This tool stores Elastic and Bounce presets as linear() strings sampled from the Penner equations so the preview looks correct.

How does the paste field work?

Paste any CSS easing – cubic-bezier(...), linear(...), four bare numbers, an array like [.4, 0, .2, 1], a full transition rule, or a named keyword (ease, ease-in, ease-out, ease-in-out, linear). The parser strips whitespace, semicolons, and surrounding code, then loads the curve. If a duration token like 500ms or 0.5s appears in the same paste, the duration slider updates too.

What do the modifier keys do?

Drag a handle to move it freely. Hold Shift while dragging to snap the handle's angle relative to its anchor in 15° increments. Hold Alt to snap to a 0.1 grid (a dashed grid appears). With the handle focused, arrow keys nudge by 0.1; add Shift for 0.01 fine control; add Alt to snap to the next grid line in the arrow direction.

What is the similarity hint?

After dragging the handles freely, the editor samples your curve at 20 points and compares it to all 24 bezier presets using RMS distance. If your curve is within ~0.06 of a named preset, a pill appears next to the title showing "≈ easeInOutCubic" (or whichever is closest). Click the pill to snap to that preset. Hover the pill to see it as a dashed overlay on your curve.

How does the preview work?

The preview uses the Web Animations API with your current easing as a CSS function. Tabs switch between three animated properties: translateX (Move), scale (Scale), and rotate (Rotate). The playback button cycles through play once, loop, and loop back and forth. Duration is adjustable. linear() easings (Elastic, Bounce) play correctly because the Web Animations API supports the linear() function natively.