The cubic-bezier() function represents one of the most powerful tools in a web developer's animation toolkit. Unlike preset easing keywords like ease or ease-out, cubic-bezier allows you to define custom timing curves that precisely control how elements accelerate, decelerate, and transition between states. By mastering these curves, you can create animations that feel organic and professional, elevating the overall user experience of your web development projects.
Understanding the Cubic Bezier Curve
At its core, a cubic Bézier curve is defined by four points: P0, P1, P2, and P3. In CSS, the start point P0 is fixed at (0, 0) and the end point P3 is fixed at (1, 1), while the intermediate control points P1 and P2 are defined by your function parameters.
The Coordinate System
The cubic-bezier() function accepts four parameters representing two control points:
x1, y1- coordinates of the first control pointx2, y2- coordinates of the second control point
The x-axis represents time (input progress) from 0 to 1, while the y-axis represents the animation progress. Critically, the x values must stay within the [0, 1] range to remain valid as a timing function, but y values can exceed these boundaries to create bounce and overshoot effects.
.element {
transition: transform 0.5s cubic-bezier(x1, y1, x2, y2);
}Valid vs Invalid Curves
For a cubic Bézier curve to be valid in CSS, the x-coordinates of both control points must be within the [0, 1] range. This ensures the curve represents a proper function where each time value maps to exactly one progress value. However, y-coordinates can exceed this range, which creates the bouncing and overshoot effects that make animations feel organic and natural.
Valid examples:
cubic-bezier(0.25, 0.1, 0.25, 1)- smooth ease-like curvecubic-bezier(0.68, -0.6, 0.32, 1.6)- elastic bounce effectcubic-bezier(0.1, 0.9, 0.9, 0.1)- S-curve for multi-stage motion
Invalid examples:
cubic-bezier(2.45, 0.6, 4, 0.1)- x values outside [0,1]cubic-bezier(-0.9, 0.3, -0.2, 2.1)- x values outside [0,1]
Custom Timing Control
Define precise acceleration and deceleration curves beyond preset easing keywords like ease or ease-out.
Elastic Bounce Effects
Create natural spring-like motion by allowing y-values to exceed boundaries, causing elements to overshoot and bounce back.
GPU-Accelerated Performance
Animate transform and opacity properties with cubic-bezier for smooth 60fps performance on all devices.
Accessibility-Conscious
Use prefers-reduced-motion media query to provide graceful fallbacks for users sensitive to animation.
Creating Elastic Bounce Effects
One of the most compelling use cases for cubic-bezier is creating elastic bounce effects without JavaScript animation libraries. By allowing the y values to go below 0 or above 1, elements can overshoot their target position and bounce back, mimicking physical spring behavior.
The Anatomy of a Bounce
Consider this bounce curve: cubic-bezier(0.8, -0.5, 0.2, 1.8)
- The first control point
(0.8, -0.5)starts the animation fast but pulls back slightly - the negative y value causes a subtle "squash" effect before the main motion - The second control point
(0.2, 1.8)overshoots the target significantly - values above 1 cause the element to push past its destination before settling back
Practical Bounce Applications
Bounce effects work exceptionally well for:
- Button interactions - adding tactile feedback when clicked
- Card reveals - creating playful entrance animations
- Notification badges - drawing attention with subtle bounces
- Loading states - indicating activity without being distracting
.button {
transform: scale(1);
transition: transform 0.5s cubic-bezier(0.8, -0.5, 0.2, 1.8);
}
.button:active {
transform: scale(0.95);
}Multi-Stage Easing for Complex Animations
Multi-stage easing allows animations to have distinct phases - starting slowly, speeding up, pausing, then finishing with another acceleration. This mirrors how objects move in the real world and creates more sophisticated, professional-feeling animations.
Understanding S-Curves
An S-curve like cubic-bezier(0.1, 0.9, 0.9, 0.1) creates an animation that:
- Starts very quickly (low x1, high y1 means rapid early progress)
- Slows dramatically in the middle (high x2, low y2 means progress stalls)
- Accelerates again to finish (returns to the destination)
Staggered List Animations
Multi-stage easing pairs beautifully with staggered animations. When multiple elements enter with overlapping cubic-bezier curves, the motion creates a wave-like flow that feels intentional and polished. This technique is particularly effective when building modern user interfaces that require smooth, coordinated entrance animations.
.list-item {
opacity: 0;
transform: translateY(30px);
animation: enter 0.7s cubic-bezier(0.5, 0, 0, 1.5) forwards;
}
.list-item:nth-child(2) { animation-delay: 0.1s; }
.list-item:nth-child(3) { animation-delay: 0.2s; }
@keyframes enter {
to {
opacity: 1;
transform: translateY(0);
}
}Performance Considerations
CSS animations using cubic-bezier are highly performant when applied correctly. The browser's compositor thread handles these animations efficiently, but understanding which properties to animate makes the difference between smooth 60fps animations and janky experiences.
For optimal performance, restrict animations to compositor-only properties:
transform- translate, scale, rotateopacity
These properties can be animated entirely on the GPU, avoiding expensive layout recalculations and repaints. When you use cubic-bezier with transform or opacity animations, the browser can achieve smooth 60fps performance even on lower-powered devices. This approach aligns with performance optimization best practices for creating fast, responsive user interfaces.
Avoiding Layout Thrashing
Avoid animating properties that trigger layout changes:
width,height,margin,paddingtop,left,right,bottom- Any property affecting element geometry
When these properties change, the browser must recalculate the entire page layout, which is computationally expensive and causes frame drops. Complement your animation strategy with proper SEO optimization to ensure fast loading times alongside smooth animations.
Best Practices for Production Use
Start with Established Curves
Before creating custom curves, experiment with proven presets:
cubic-bezier(0.4, 0, 0.2, 1)- Material Design standardcubic-bezier(0.4, 0, 0, 1)- sharp, precise motioncubic-bezier(0.4, 0, 0.6, 1)- subtle ease for longer animations
Respect User Preferences
Always respect user motion preferences using the prefers-reduced-motion media query:
@media (prefers-reduced-motion: reduce) {
.animated-element {
transition: transform 0.1s ease;
}
}
Use Interactive Tools
Creating effective cubic-bezier curves is challenging to do by hand. Use interactive tools like cubic-bezier.com to visualize curves in real-time, adjusting control points and immediately seeing how the animation feels.
Document Custom Curves
When using custom cubic-bezier curves across a project, document them in a central location:
:root {
--ease-bounce: cubic-bezier(0.68, -0.6, 0.32, 1.6);
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
--ease-spring: cubic-bezier(0.5, 0, 0, 1.5);
}
Summary
The cubic-bezier() function transforms CSS animations from basic transitions into sophisticated motion experiences. By understanding the math behind the curve and experimenting with control point values, you can create animations that feel natural, responsive, and professionally crafted.
Key takeaways:
- The x-coordinates must stay within [0, 1], but y-values can exceed this range for bounce effects
- Negative y values create anticipation and "squash" effects
- Y values above 1 create overshoot and "bounce" effects
- Always animate compositor-only properties (transform, opacity) for best performance
- Respect user preferences with
prefers-reduced-motion - Start with established curves before creating custom ones
Mastering cubic-bezier curves is a valuable skill for any web developer looking to create polished, engaging user interfaces. For more advanced CSS techniques, explore our guide on native CSS nesting to further modernize your stylesheet architecture.
Sources
- CSS-Tricks: cubic-bezier() - Comprehensive guide covering syntax, practical examples, and comparison with other timing functions
- MDN Web Docs: cubic-bezier() - Official documentation with formal syntax, browser support, and technical specifications