CSS Easing Function Generator
Build cubic-bezier curves visually and generate CSS transition / animation code
Easing Function
easecubic-bezier(0.25, 0.1, 0.25, 1)
P1 (x, y)
P2 (x, y)
Presets
Animation Preview
Generated CSS
.element {
transition: transform 600ms ease;
}Compare Easings
Add easings to compare side by side.
Your modal slides in with ease and it feels… fine. Not snappy, not elegant, just default. You know cubic-bezier() can make it feel like a native app — that satisfying deceleration curve iOS uses — but the four control point values are meaningless without a visual editor. You need to see the curve, drag the handles, and watch the animation play back before committing.
Why This Tool (Not Easings.net or Chrome DevTools)
Easings.net shows named curves but doesn’t let you create custom ones. Chrome DevTools has a cubic-bezier editor buried three clicks deep that only works on existing properties. This tool gives you a full-screen drag editor for cubic-bezier() control points, a steps() builder, real-time animation preview, and one-click CSS copy. Everything runs in your browser; no data is sent anywhere.
What Is a CSS Easing Function?
A CSS easing function (also called a timing function) controls how an animation or transition progresses over time. Instead of moving at a constant speed, you can make elements accelerate, decelerate, bounce, or snap between states. Easing is what separates polished, natural-feeling UI from rigid, mechanical movement.
CSS supports two main families of timing functions:
- cubic-bezier() — a smooth curve defined by two control points
- steps() — a stepped function that jumps between discrete states
Understanding cubic-bezier()
The cubic-bezier(x1, y1, x2, y2) function defines a curve through four points: a fixed start point (0, 0), two user-defined control points P1 and P2, and a fixed end point (1, 1). The x-axis represents elapsed time (always 0–1) while the y-axis represents the animation’s progress value.
Control point constraints:
x1andx2must be in the range[0, 1]— time cannot go backwardsy1andy2can be outside[0, 1]for overshoot and anticipation effects
The browser solves for y at each time x using the cubic bezier parametric equations, producing a smooth easing curve.
The Five CSS Standard Keywords
| Keyword | cubic-bezier equivalent | Character |
|---|---|---|
ease | cubic-bezier(0.25, 0.1, 0.25, 1) | Fast start, slow end |
ease-in | cubic-bezier(0.42, 0, 1, 1) | Slow start, fast end |
ease-out | cubic-bezier(0, 0, 0.58, 1) | Fast start, gentle end |
ease-in-out | cubic-bezier(0.42, 0, 0.58, 1) | Slow start and end |
linear | cubic-bezier(0, 0, 1, 1) | Constant speed |
Material Design Easing
Google’s Material Design system defines four standard easing curves:
- Standard:
cubic-bezier(0.4, 0, 0.2, 1)— most elements entering and leaving the screen - Decelerate:
cubic-bezier(0, 0, 0.2, 1)— elements entering the screen - Accelerate:
cubic-bezier(0.4, 0, 1, 1)— elements permanently leaving the screen - Sharp:
cubic-bezier(0.4, 0, 0.6, 1)— objects that may return to the screen
Apple / iOS Easing
iOS animations use spring-based physics, but the closest CSS cubic-bezier approximations are:
- iOS Default:
cubic-bezier(0.25, 0.46, 0.45, 0.94)— smooth, natural deceleration - iOS Keyboard:
cubic-bezier(0.13, 1, 0.49, 1)— the characteristic iOS keyboard slide
Understanding steps()
The steps(n, direction) function creates discrete, stepped animation. Instead of a smooth curve, the element jumps to n equally spaced positions.
Direction values:
steps(n, end)— jumps happen at the end of each interval (default)steps(n, start)— jumps happen at the start of each intervalsteps(n, both)— jumps at both start and end (n+1 visible steps)steps(n, none)— no jump at start or end (only works well mid-animation)
Common uses for steps():
- Sprite sheet animation (frame-by-frame)
- Typewriter / character reveal effects
- Progress indicators with discrete steps
- Retro pixel-art style animations
Using Easing Functions with CSS Transitions
/* Smooth card hover */
.card {
transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.card:hover {
transform: scale(1.05);
}
/* Material Design enter */
.modal {
transition: opacity 250ms cubic-bezier(0, 0, 0.2, 1),
transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
Using Easing Functions with CSS Animations
/* Bounce in */
@keyframes bounceIn {
from { transform: scale(0.8); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.element {
animation: bounceIn 400ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
/* Typewriter with steps */
@keyframes type {
from { width: 0; }
to { width: 20ch; }
}
.typewriter {
overflow: hidden;
white-space: nowrap;
animation: type 2s steps(20, end) forwards;
}
Tips for Choosing the Right Easing
For entering elements — use deceleration (ease-out family): fast start ensures users see the element immediately; gentle end feels natural.
For exiting elements — use acceleration (ease-in family): element appears to gain momentum as it leaves.
For emphasis or feedback — use overshoot easing (back-out, spring): the slight overshoot draws attention and feels lively.
For loading states — use ease-in-out or a symmetric spring: the symmetry creates a calm, looping feel.
For sprite animations — use steps() to snap between frames without interpolation.
Frequently Asked Questions
Can y values be negative or greater than 1?
Yes. When y1 or y2 is outside [0, 1], the animation overshoots or undercuts its target, creating spring-like or anticipation effects. Only x1 and x2 are constrained to [0, 1].
What is the difference between ease-in and ease-out? Ease-in starts slowly and speeds up (like a car accelerating), while ease-out starts quickly and slows down (like a car braking). Ease-out generally feels more responsive because users see the movement immediately.
Is cubic-bezier() supported in all browsers?
Yes. All modern browsers (Chrome, Firefox, Safari, Edge) and even IE10+ support cubic-bezier() for both transition-timing-function and animation-timing-function.
What is the difference between steps(n, start) and steps(n, end)?
steps(n, end) shows the first frame for the first interval and the last frame never shows. steps(n, start) shows the last frame at the end and the first frame never shows. For sprite animations, steps(n, end) is usually correct.
Can I use the same easing for transition and animation?
Yes. The cubic-bezier() and steps() syntax works identically for both transition-timing-function and animation-timing-function properties.