What Are Easing Functions?
Easing functions are mathematical formulas that describe the rate of change in an animation or transition. They control how elements progress from their starting state to their ending state over time, dictating the acceleration and deceleration curves that give movement its character. Without easing, all CSS transitions and animations would move at a constant speed--the visual equivalent of a robot arm moving with mechanical precision.
The CSS easing functions module defines three primary types:
-
Cubic-bezier curves -- smooth, continuous curves that simulate natural acceleration and deceleration. These are the workhorses of modern web animation, providing organic movement that mimics how objects behave in the physical world. From MDN's documentation, cubic-bezier functions accept four parameters that define control points shaping the curve.
-
Linear easing -- maintains constant speed throughout the animation. While rarely the most visually appealing choice, linear easing has its place for continuous animations like loading indicators, progress bars, or any animation where a steady pace is explicitly desired.
-
Step functions -- create discrete, frame-by-frame movement for retro or mechanical effects. The
steps()function breaks animations into equal-duration steps, perfect for typewriter text effects, pixel-art animations, and loading indicators that snap between states.
Easing functions are applied through the transition-timing-function and animation-timing-function CSS properties, making them compatible with all CSS transitions and animations. They work by modifying how the browser calculates intermediate values between start and end states, interpolating based on the easing curve rather than simple linear progression. For professional web development services that prioritize user experience, mastering easing functions is essential for creating interfaces that feel polished and professional.
As covered in CSS-Tricks' timing function guide, the choice of easing significantly impacts user perception of interface quality.
Key concepts for mastering CSS animation timing
Cubic-Bezier Foundation
Learn how the four-parameter cubic-bezier function defines smooth curves that control animation timing and feel.
Standard Easing Keywords
Master the built-in easing keywords (ease, ease-in, ease-out, ease-in-out) and their cubic-bezier equivalents.
Step Functions
Create discrete, frame-by-frame animations using steps() for typewriter effects and retro aesthetics.
Performance Optimization
Implement performant animations that run smoothly on all devices without impacting page load.
The Cubic-Bezier Foundation
The cubic-bezier function is the workhorse of CSS easing, defining smooth curves that control animation timing. Every easing keyword in CSS--from ease to ease-in-out--is ultimately implemented as a cubic-bezier curve.
Syntax
transition: all 0.3s cubic-bezier(x1, y1, x2, y2);
The four parameters represent control points that shape the curve:
- x1, y1 -- The first control point (starting slope)
- x2, y2 -- The second control point (ending slope)
Understanding the Coordinate System
The coordinate system for cubic-bezier uses the x-axis representing time (from 0 to 1, representing the start to end of the animation) and the y-axis representing progress (also from 0 to 1). The curve connects two fixed points: the origin (0,0) and destination (1,1), with control points that determine the curvature.
What makes cubic-bezier particularly powerful is that the y values can extend beyond the 0-1 range, creating overshoot effects where the animation goes beyond its target value before settling back. This enables the elastic and bounce effects that make UI interactions feel playful and responsive. The x values, however, must remain between 0 and 1 since time cannot flow backward.
When you create a curve like cubic-bezier(0.34, 1.56, 0.64, 1), the y value of 1.56 means the animation will overshoot its target by 56% before returning--a springy effect perfect for action buttons that need to feel energetic. According to Josh Collinsworth's visual explanation, understanding this coordinate system is essential for crafting precise animation feels.
For more advanced CSS animation techniques, explore our guide on CSS keyframes to combine easing functions with multi-step animations.
| Keyword | Cubic-Bezier | Use Case |
|---|---|---|
| ease | cubic-bezier(0.25, 0.1, 0.25, 1) | General UI transitions, hover states |
| ease-in | cubic-bezier(0.42, 0, 1, 1) | Elements entering viewport |
| ease-out | cubic-bezier(0, 0, 0.58, 1) | Elements leaving viewport |
| ease-in-out | cubic-bezier(0.42, 0, 0.58, 1) | Natural organic motion |
| linear | cubic-bezier(0, 0, 1, 1) | Loading indicators, progress bars |
Step Functions for Discrete Animation
Step functions create discrete jumps between states rather than smooth transitions. The steps() function breaks animations into equal-duration steps, creating a frame-by-frame or stop-motion effect.
Syntax
animation: reveal 1s steps(4, end) forwards;
Parameters
- n -- Number of steps
- direction --
start,end,jump-start,jump-end,jump-both,jump-none
Use Cases
Typewriter Effects -- The classic typewriter effect uses steps() to reveal one character at a time. The end direction creates a brief pause at each character before the reveal, mimicking the mechanical rhythm of a real typewriter.
Retro Animations -- Pixel-art and 8-bit aesthetics benefit from step-based movement that maintains the blocky, quantized feel. Games and nostalgic interfaces use steps to preserve authenticity.
Loading Indicators -- Progress meters that snap between discrete states (like a battery charging or steps completed) use steps for clean, predictable visual updates that are easy to scan.
Navigation Indicators -- Tab switches, pagination dots, or step wizards that need to snap between positions rather than glide use step functions for deterministic, mechanical feedback.
The start value creates the first step immediately at time zero, while end creates the first step at the end of the first interval. For MDN's complete reference, the jump-both value includes both start and end points, useful for animations that need to feel complete at both extremes.
Related to this topic, our guide on CSS transforms shows how to combine step animations with transform properties for complex motion effects.
1.button {2 transform: scale(1);3 transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);4}5 6.button:hover {7 transform: scale(1.05);8}9 10.button:active {11 transform: scale(0.98);12}1.modal-overlay {2 opacity: 0;3 transition: opacity 0.3s cubic-bezier(0, 0, 0.2, 1);4}5 6.modal-content {7 transform: translateY(20px) scale(0.95);8 transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);9}10 11.modal-overlay.open {12 opacity: 1;13}14 15.modal-overlay.open .modal-content {16 transform: translateY(0) scale(1);17}1.list-item {2 opacity: 0;3 transform: translateY(10px);4 animation: listEnter 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;5}6 7.list-item:nth-child(1) { animation-delay: 0ms; }8.list-item:nth-child(2) { animation-delay: 100ms; }9.list-item:nth-child(3) { animation-delay: 200ms; }10.list-item:nth-child(4) { animation-delay: 300ms; }11 12@keyframes listEnter {13 to {14 opacity: 1;15 transform: translateY(0);16 }17}Performance Considerations for Production Applications
Compositable Properties
For smooth 60fps animations, animate only compositable properties:
| Property | Performance | Recommendation |
|---|---|---|
transform | Excellent | Preferred for animations |
opacity | Excellent | Preferred for fades |
filter | Good | Usable with care |
width, height | Poor | Triggers layout |
margin, padding | Poor | Triggers layout |
Using will-change
.card {
/* Prepare for animation */
will-change: transform;
}
.card:hover {
transform: scale(1.05);
}
Note: Use will-change sparingly. Overuse increases memory consumption.
Duration Guidelines
Duration and easing work together to determine perceived animation speed. Target 150-500ms for most interactive transitions, with 200-300ms being optimal for typical UI interactions. Match easing intensity to duration--subtle easing works with shorter durations, while more pronounced easing effects may need slightly longer durations to feel natural.
For Next.js applications specifically, consider the impact on page load and Core Web Vitals. Avoid animating elements above the fold during initial render. Defer non-essential animations until after hydration, and use Intersection Observer to trigger animations only when elements enter the viewport. This approach ensures your animations enhance rather than hinder user experience.
As noted in CSS-Tricks' performance guide, the browser's compositor thread can handle transform and opacity animations separately from the main JavaScript thread, enabling smooth performance even during heavy operations.
Optimizing animations is part of broader web performance optimization that includes proper asset loading, code splitting, and efficient rendering patterns.
Accessibility and Reduced Motion
Respect user preferences for reduced motion using the prefers-reduced-motion media query:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
@media (prefers-reduced-motion: no-preference) {
.button {
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
}
Accessible Animation Patterns for Next.js
For Next.js applications specifically, integrate accessibility considerations into your component architecture:
Create Animation Variants -- Use libraries like Framer Motion that handle reduced motion preferences automatically, or create your own variant system that responds to prefers-reduced-motion.
Provide Alternatives -- For interactive elements with motion as core feedback (like toggle switches or animated icons), provide non-animated alternatives that maintain functionality without motion.
Test Across Preferences -- Always test your interfaces with motion preferences enabled in system settings. What feels natural to some users can cause discomfort or disorientation for others with vestibular disorders.
Best Practices
- Never animate elements above the fold during initial page load
- Defer non-essential animations until after hydration
- Provide fallbacks for essential animations
- Test with motion preferences enabled on all devices
- Keep animations purposeful -- every animation should serve a clear user experience goal
Per MDN's accessibility guidelines, many users experience discomfort from motion on screens. Respecting system preferences demonstrates attention to inclusive design and ensures your applications are usable by everyone.
Accessibility in animations also impacts search engine optimization, as search engines increasingly consider user experience signals when ranking websites.
Creating Custom Easing Curves
Establish a design system of named easing curves using CSS custom properties:
:root {
--ease-snappy: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
--ease-gentle: cubic-bezier(0.25, 0.1, 0.25, 1);
--ease-elastic: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.button {
transition: transform 0.2s var(--ease-snappy);
}
.card {
transition: transform 0.3s var(--ease-smooth);
}
.tooltip {
transition: opacity 0.2s var(--ease-gentle);
}
When to Use Custom Curves
- Snappy easing (values > 1): Action buttons, interactive elements where you want immediate feedback with a playful bounce
- Smooth easing (standard curves): Content transitions, modals, and navigation where you want predictable, professional motion
- Gentle easing (subtle curves): Text, images, and informational elements where motion should be barely perceptible
- Elastic easing (overshoot): Special moments like successful actions, celebrations, or attention-grabbing moments
Browser DevTools for Curve Editing
Modern browser developer tools include easing curve editors that let you visualize and adjust curves in real time:
- Chrome DevTools: Open the Styles panel, find your cubic-bezier value, click the curve icon to open the visual editor
- Firefox Developer Edition: Similar visual editor accessible from the Rules view
- Safari Web Inspector: Provides curve visualization in the Computed panel
These tools let you drag control points to create custom curves, preview the animation, and copy the resulting CSS directly. This visual approach makes it easier to iterate on easing curves without memorizing coordinate values.
Team Collaboration on Easing Systems
For collaborative development teams, document your easing system in your design system or component library. Establish clear guidelines for when each easing curve should be used, ensuring consistency across features. The Josh Collinsworth guide recommends creating a shared vocabulary--call your curves by descriptive names (snappy, smooth, gentle) rather than just values, making communication about animation design clearer.
Creating a cohesive animation system is part of building a maintainable React component library where consistency and reusability are priorities.
Frequently Asked Questions
Conclusion
Easing functions transform CSS transitions and animations from mechanical movements into polished, natural-feeling interactions. By understanding how cubic-bezier curves work, when to use standard easing keywords versus custom curves, and how to implement animations accessibly, you gain a powerful tool for creating interfaces that feel refined and professional.
The key is intentionality--choose easing that serves the purpose of each interaction, and test across devices to ensure smooth performance. With these fundamentals, you're equipped to bring fluid, engaging motion to any web application built with Next.js or any modern framework.
Key Takeaways
- Cubic-bezier functions provide the foundation for all CSS easing
- Standard keywords (ease, ease-in, ease-out, ease-in-out) cover most use cases
- Step functions create discrete animations for typewriter and retro effects
- Performance matters--animate only transform, opacity, and filter
- Accessibility is essential--respect prefers-reduced-motion
- Custom curves create unique animation personalities when needed