Cubic Bezier Generator
The CSS keyword ease is cubic-bezier(0.25, 0.1, 0.25, 1). Drag the two handles on the graph, or use the arrow keys, to shape your own curve and watch it animate. The spring tab turns mass, stiffness and damping into a linear() easing, for example about 646 ms for mass 1, stiffness 170, damping 26.
How to use
- Pick a preset or drag the two handles on the graph. With the keyboard, focus a handle and use the arrow keys (hold Shift for bigger steps). You can also type the four numbers or paste an existing cubic-bezier() value.
- Set a duration and press Play to see the curve move the box. The preview loops unless your system asks for reduced motion.
- Copy the cubic-bezier() value into transition-timing-function or animation-timing-function. For a bounce or overshoot with natural settling, switch to the Spring tab, set mass, stiffness and damping, and copy the linear() value with its duration.
How it works
A cubic-bezier(x1, y1, x2, y2) curve runs from (0, 0) to (1, 1) with two control points. The horizontal axis is time progress and the vertical axis is how far the animation has gone. x1 and x2 must stay between 0 and 1 so time never runs backwards, while y1 and y2 may go outside that range to overshoot or pull back first. The graph here shows y from -0.6 to 1.6.
To find the value at a time x, the tool solves x(t) = x for the curve parameter t with Newton's method, falls back to bisection when the slope is flat, and then reads y(t). The standard keywords are fixed curves: ease is (0.25, 0.1, 0.25, 1), ease-in is (0.42, 0, 1, 1), ease-out is (0, 0, 0.58, 1) and ease-in-out is (0.42, 0, 0.58, 1).
The spring uses the step response of a damped mass-on-a-spring with no initial velocity. The natural frequency is √(stiffness ÷ mass) and the damping ratio is damping ÷ (2 × √(stiffness × mass)). Below 1 the motion overshoots and rings, at 1 it settles fastest without overshoot, and above 1 it creeps in slowly.
CSS has no spring easing, so the curve is sampled into 49 evenly spaced values and written as linear(), which draws straight lines between them. The duration is the time after which the spring stays within 0.2 percent of its target, capped at 10 seconds. It is an approximation: the result is smooth enough to look like a spring, but it is not the exact curve.
FAQ
How do I use the result?
Put it in a timing-function property, for example transition: transform 400ms cubic-bezier(0.25, 0.1, 0.25, 1). For a spring, use the linear() value together with the duration shown, for example transition: transform 650ms linear(0, 0.2, ...).
Why can y go above 1 or below 0 but not x?
The x values are time and CSS requires them to stay between 0 and 1. The y values are progress, so going past 1 makes the element overshoot its target and below 0 makes it pull back first. easeOutBack and easeInBack use this.
Which browsers support linear()?
Current versions of Chrome, Edge, Firefox and Safari. In an older browser the declaration is ignored and the default easing applies, so add a cubic-bezier() line before it as a fallback.
Why is the spring result not exact?
linear() joins sampled points with straight lines, so it can only approximate a smooth curve. 49 points are enough to look natural for typical UI motion. The overshoot and duration shown come from the exact formula, not from the sampled points.
Can I use it with JavaScript animation libraries?
Yes. The Web Animations API accepts both cubic-bezier() and linear() as the easing option, and most libraries accept a cubic-bezier array of four numbers.