You should generate a CSS cubic bezier whenever the five built-in easing keywords — linear, ease, ease-in, ease-out, and ease-in-out — do not match the motion your interface actually needs, and when the timing itself is what you want to fine-tune rather than the duration, distance, or property being animated. A cubic bezier curve defines the speed at which an animated value progresses from zero to one over the duration of a transition, and CSS expresses it as four control coordinates inside a cubic-bezier(x1, y1, x2, y2) function. The browser plots the curve, samples the elapsed time along the horizontal axis, and uses the curve's vertical output as the actual fraction of the animation that has completed. Default keywords cover most interfaces well, so the decision to generate a custom curve is usually justified by a specific reason: a sharper entry, a softer landing, a deliberate overshoot, or a brand-specific feel that no preset reproduces. If none of those reasons apply, the keywords alone are usually enough, and no generation step is needed at all.

When the Built-In Keywords Are Enough
CSS defines five easing keywords, and each one maps to a standardized set of control points defined in the W3C CSS Easing Functions Level 1 specification. Because those mappings are standardized, any browser rendering the same keyword produces the same motion. That uniformity is a feature, not a limitation: predictable timing is what lets a design system scale across components, breakpoints, and contributors without surprise. If your interface looks right with a default keyword, leaving it in place keeps your stylesheet readable and your animation behavior identical to every other site that uses the same keyword.
The keywords also remove the maintenance cost of bespoke curves. A custom cubic-bezier value is something future contributors must understand before they feel safe changing it; a keyword is self-documenting. Before deciding to generate, scan the surface you actually animate. Tooltips, fades, simple reveals, hover lifts, and most modals settle into one of the keywords without complaint. Reach for a custom curve only when a keyword has visibly failed your motion goal, not because custom feels more sophisticated.
Reasons That Justify Generating a Custom Curve
Custom cubic-bezier easing earns its place when one of a small number of motion problems shows up in your interface. These are the conditions where generation is the right next step rather than a premature optimization.
- Brand-specific feel. A motion language defined in your design system needs more than ease-in-out can express — a sharper click, a softer settle, or a particular acceleration profile you can already describe but cannot reach with a keyword.
- Sharper entry or softer landing. Buttons, toggles, and notifications often want a fast start and a gentle end, or the inverse, in a proportion the standard keywords don't quite hit.
- Deliberate overshoot or anticipation. Playful UI elements — a confirmation check that bounces, a card that pops past its resting position — rely on y values that leave the zero-to-one range. None of the five keywords can do that.
- Eliminating the "robotic" feel. Symmetric easing on long transitions reads as mechanical. A slightly asymmetric custom curve makes the same transition feel designed rather than defaulted.
- Replacing JavaScript for simple timing. When a library is being used only to tweak the easing of a CSS transition, a custom cubic-bezier value can remove the dependency entirely.
The Five Keyword-to-Curve Mappings
When you open the CSS Cubic Bezier Generator, its preset buttons load the standardized control points from the W3C CSS Easing Functions Level 1 specification rather than emitting the keyword itself. The generator exposes all four numbers in the output so the value can be recorded, compared, and modified without hidden defaults. The table below lists the standardized mappings you can reference.
| Keyword | Equivalent cubic-bezier() | Motion character |
|---|---|---|
| linear | cubic-bezier(0, 0, 1, 1) | Constant speed from start to end |
| ease | cubic-bezier(0.25, 0.1, 0.25, 1) | Default; gentle acceleration, long deceleration |
| ease-in | cubic-bezier(0.42, 0, 1, 1) | Slow start, accelerates toward the end |
| ease-out | cubic-bezier(0, 0, 0.58, 1) | Fast start, decelerates toward the end |
| ease-in-out | cubic-bezier(0.42, 0, 0.58, 1) | Slow start and end, fastest in the middle |
Source: W3C CSS Easing Functions Level 1. If any of these shapes already match your intent, the keyword is the right answer; a custom curve only adds value when the shape you want diverges from every row above.
How to Generate a CSS Cubic Bezier
Once you have decided that a default keyword doesn't fit, the CSS Cubic Bezier Generator turns the four control coordinates into a standards-compatible transition-timing-function declaration in the browser, with no upload or storage of your values.
- Open the generator and start either from one of the five preset keyword buttons or with the four coordinate fields empty if you already have target numbers in mind.
- Drag the control handles on the graph, or type x1, y1, x2, and y2 directly. Keep x1 and x2 between 0 and 1 — CSS treats any other value as invalid and discards the entire declaration.
- Read the input-to-output sample table while you adjust. It tells you the actual progress reached at 0, 0.25, 0.5, 0.75, and 1 of elapsed time, which is the answer the curve diagram alone does not give.
- Toggle the Run preview to watch a circle transition between two positions over 900 ms using your exact easing string. Click repeatedly to compare forward and reverse motion.
- Copy the complete transition-timing-function declaration and paste it into your stylesheet alongside the property, duration, delay, and any reduced-motion handling you have already chosen.
For a deeper walk-through of the steps and what to look for at each stage, see the guide on checking the result after you generate a CSS cubic bezier.
Validity Rules That Decide Whether the Browser Accepts Your Curve
CSS is strict about what counts as a valid cubic-bezier value, and the generator enforces the same rules at the input layer so you can see invalid input rejected before you copy anything.
- x1 and x2 must stay within [0, 1]. They describe input-time positions. If either falls outside the closed zero-to-one range, the entire cubic-bezier() declaration is invalid and the property falls back to its default easing.
- y1 and y2 may leave [0, 1]. They describe output progress, and values below zero create anticipation while values above one create overshoot. The generator's interface accepts finite y values from −10 to 10 and validates them in the browser before producing output.
- The curve always starts at (0, 0) and ends at (1, 1). Only the two intermediate control points are editable, which is why the four-coordinate format has stayed stable since CSS Transitions Level 1.
- Calculation stays in the browser. No curve, CSS, or interaction data is uploaded, stored, or sent to an animation service, so the value you generate is reproducible offline.
These rules are documented in the W3C CSS Easing Functions Level 1 specification and on MDN's cubic-bezier() reference page.
Accessibility and Reduced-Motion Considerations
A valid curve is not automatically appropriate. Large overshoots can make controls appear to reverse direction, leave their container, or reveal content that was expected to remain clipped, and any of those side effects can disorient users or interfere with focus and pointer behavior while an element is transitioning. Rapid oscillation across many cycles compounds the problem. The W3C specification defines only what is syntactically valid; it does not decide whether a given curve is humane.
Always test the copied declaration in its final interface, not just in the generator's preview, and respect prefers-reduced-motion where animation is not essential. The preview demonstrates timing on a single property at one duration; a real component can feel different when distance, duration, property, rendering cost, input device, or surrounding motion changes. If state changes need to remain understandable without motion, make sure the non-animated state already communicates the outcome, then layer the curve on top.
When a Different Tool Is the Better Choice
The CSS Cubic Bezier Generator outputs only transition-timing-function. It does not generate keyframes, spring physics, linear() stop lists, steps(), duration, delay, iteration count, or a full transition shorthand. The decision to use the generator should be made alongside a quick check that none of those adjacent capabilities is what you actually need.
- Need a full transition shorthand. Write the shorthand by hand. The generator deliberately stops at the timing function so the rest of the declaration stays predictable and easy to audit.
- Need spring physics. Spring motion is energy-based, not timing-based, and adjusts when an animation is interrupted. CSS cubic-bezier is deterministic and timing-based. Pick a JavaScript animation library.
- Need multi-step animation. Use CSS @keyframes with multiple animation-timing-function declarations per keyframe.
- Need stepped motion or a stop list. Use steps() or linear() directly — these are different easing functions, not cubic-bezier values.
After you copy the declaration, the last step is verifying it behaves as expected in the real component. The generator shows you the curve shape and a 900 ms preview, but production timing is the only timing that matters for your users, and that test always happens inside the component that ships.
Related reading: How Do I Decide Whether I Need a CSS Toggle Switch?.