⧔ Cubic Bezier Editor
Visual CSS timing function editor with live preview.
Last updated: June 9, 2026 · By Λ
Preview
Click the CSS to copy. Snaps to grid when dragging close to integer tenths.
By Λ · Updated June 9, 2026 · ~3 min read
What a cubic-bezier is, briefly
A cubic-bezier function describes a curve between (0,0) and (1,1) using two control points. In CSS, that curve maps animation progress (x-axis, time) to visual progress (y-axis, position). linear is a straight line; ease-in-out curves S-shaped; back overshoots before settling. The editor lets you drag the two control points and see the resulting curve and animation in real time.
Picking the right curve
Linear is rarely right for UI animations. It feels mechanical because nothing in the real world moves at constant velocity.
Ease-out is the safe default for things appearing on screen. Fast start, soft landing.
Ease-in is the right choice for things leaving the screen. Soft start, fast exit.
Ease-in-out is for movement that starts and ends in motion. Tabs sliding, pages flipping, modal panels.
Custom curves with overshoot (control y values outside 0-1) give springy or bouncy effects. Use sparingly; they age badly.
The y outside [0,1] trick
CSS allows y values above 1 or below 0 in cubic-bezier. The animation overshoots the target before settling. The classic "back" easing uses values like cubic-bezier(0.68, -0.55, 0.27, 1.55). Useful for affordance: telling the user "this thing has weight". Overuse looks cartoonish.
How this editor works
The graph maps time on the horizontal axis to progress on the vertical, both normalized to a 0-1 range. Drag the blue P1 handle to shape how motion starts and the red P2 handle to shape how it ends, or type exact coordinates in 0.01 steps. Dragging clamps x between 0 and 1, since CSS rejects anything wider, while y stays free for overshoot. Presets cover linear, the ease family, a back curve at (0.68, -0.55, 0.27, 1.55), and a single-overshoot bounce at (0.175, 0.885, 0.32, 1.275). The output line rounds each value to three decimals, and the preview ball replays your curve at durations from 0.3s to 3s. Since the editor is plain JavaScript driving an SVG, the curves you sketch never get sent off your machine.
Worked example
Say a dropdown should land with a small spring. Start from ease-out, drag P1 until the fields read x 0.20, y 1.40, and set P2 to x 0.60, y 0.95. The output becomes animation-timing-function: cubic-bezier(0.200, 1.400, 0.600, 0.950);, one click from your clipboard. Played at the default 1.2s, the ball overshoots its endpoint and settles back, the signature of a y above 1.
Limitations and edge cases
One bezier segment allows at most a single overshoot, so a genuine multi-bounce cannot be expressed here; reach for @keyframes or the newer linear() function instead. The number fields accept anything you type, including x values past 1, and browsers respond by silently dropping the rule. Copying relies on the async clipboard API, available only on HTTPS pages. The same four numbers also work in transition-timing-function.
Frequently Asked Questions
What do the four numbers control?
They are control-point coordinates: x1 and y1 place P1, x2 and y2 place P2. The endpoints are pinned at (0,0) and (1,1), so those four values define the entire easing.
Why can y escape the 0-1 range when x cannot?
X is time, and a timing function must return one progress value per moment, pinning x1 and x2 inside 0-1. Progress may overshoot the target or dip behind the start.
Is the preview an approximation?
No. Play assigns your curve to a genuine CSS transition on the ball, so the motion comes straight from the browser's animation engine.
Related CSS animation tools
For colors that animate well, see the color picker with OKLCH support. For complete CSS layouts with timing, see the CSS layout generator. There's a blog post on modern CSS color that touches on gradient interpolation, which also benefits from picking the right curve.