Easing Functions in CSS: A Complete Guide to Smooth Animations

Transform robotic transitions into natural motion. Learn how easing functions control animation rate of change for polished, intuitive user experiences.

Easing functions are the secret ingredient that transforms mechanical, robotic motion into smooth, natural transitions that feel intuitive to users. When you hover over a button that gently accelerates into view or a modal that decelerates to a soft landing, you're experiencing the power of easing at work.

This guide covers everything you need to master easing functions in CSS, from basic built-in keywords to advanced custom curves that create spring-like physics without JavaScript. Master these techniques as part of a comprehensive web development strategy to create interfaces that feel polished and professional.

What Are Easing Functions?

Easing functions define the rate of change of a value over time during an animation or transition. They control how an element moves between states, creating natural motion instead of linear (robotic) movement.

The Physics Behind Easing

Objects in the real world don't move at constant speeds--they accelerate, decelerate, and respond to forces like gravity and friction. A ball dropped from a height starts slow, accelerates due to gravity, then bounces and decelerates. Easing functions replicate these natural motion patterns, making digital interfaces feel more intuitive.

Linear vs Eased Animation Comparison
1/* Linear: Constant speed - feels robotic */2.element-linear {3 transition: transform 0.3s linear;4}5 6/* Ease: Default - slightly better but still mechanical */7.element-ease {8 transition: transform 0.3s ease;9}10 11/* Custom cubic-bezier: Natural, polished motion */12.element-smooth {13 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);14}

Built-in Easing Keywords

CSS provides five built-in easing keywords that cover most common use cases. Understanding when to use each is essential for creating polished interfaces.

KeywordBehaviorBest Use Cases
linearConstant speedLoaders, continuous motion
easeSlight start/end, fast middleDefault transitions
ease-inSlow start, fast endElements entering view
ease-outFast start, slow endElements exiting view
ease-in-outSlow start/end, fast middleGeneral smooth transitions
Built-in Keyword Examples
1/* Continuous mechanical motion */2.loader {3 animation: spin 1s linear infinite;4}5 6/* Default transition - general purpose */7.card {8 transition: transform 0.3s ease;9}10 11/* Slow acceleration - elements entering */12.modal-enter {13 animation: fadeIn 0.3s ease-in;14}15 16/* Deceleration - elements exiting */17.modal-exit {18 animation: fadeOut 0.3s ease-out;19}20 21/* Smooth throughout - balanced motion */22.smooth-transition {23 transition: all 0.4s ease-in-out;24}

Custom Easing with cubic-bezier()

The cubic-bezier() function is your primary tool for creating custom easing curves. Unlike keywords, it gives you complete control over the acceleration curve.

Understanding the Syntax

cubic-bezier(x1, y1, x2, y2) defines a custom curve using two control points:

  • P1 (x1, y1): First control point
  • P2 (x2, y2): Second control point
  • X values must be 0-1 (time cannot go backward)
  • Y values can exceed 0-1 for bounce effects

Recommended Presets

Presetcubic-bezier ValueFeel
Material Design0.4, 0, 0.2, 1Smooth, natural
iOS Swift Out0.55, 0, 0.4, 1iOS-style deceleration
Apple Standard0.5, 0, 0.25, 1Refined, subtle
Elastic0.68, -0.55, 0.265, 1.55Bouncy, playful
Custom Cubic-Bezier Examples
1/* Material Design standard easing */2.material {3 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);4}5 6/* Subtle bounce effect */7.bouncy {8 transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);9}10 11/* Elastic button press */12.button:active {13 transform: scale(0.95);14 transition: transform 0.1s cubic-bezier(0.4, 0, 0.2, 1);15}16 17/* Spring-like card hover */18.card:hover {19 transform: translateY(-4px);20 transition: transform 0.3s cubic-bezier(0.3, 0, 0, 1.5);21}

Step Functions for Discrete Animations

The steps() function creates frame-by-frame or sprite-sheet animations by dividing the transition into discrete jumps instead of smooth motion.

Step Direction Modifiers

ValueBehavior
steps(4, jump-start)Jump at 0%, 25%, 50%, 75%
steps(4, jump-end)Jump at 25%, 50%, 75%, 100%
steps(4, jump-both)Jump at 0%, 33%, 66%, 100%
steps(4, jump-none)Smooth between intervals

Use cases: retro animations, loading indicators, progress meters, countdown timers.

Step Function Examples
1/* Sprite sheet animation - 8 frames */2.sprite {3 animation: walk 0.8s steps(8) infinite;4}5 6/* Loading indicator with 4 steps */7.loading-dots span {8 animation: dots 1s steps(4) infinite;9}10 11/* Jump-start: appear immediately */12.character {13 animation: walk 0.5s steps(6, jump-start) infinite;14}15 16/* Jump-end: appear after first frame (default) */17.character {18 animation: walk 0.5s steps(6, jump-end) infinite;19}

The Modern linear() Function

The linear() function creates complex easing curves using linear segments. Unlike the linear keyword (constant speed), it can create variable speed motion with precise control.

When to Use linear() vs cubic-bezier()

  • Use cubic-bezier() for most custom easing--intuitive and well-supported
  • Use linear() for complex multi-segment curves that cubic-bezier cannot achieve
  • linear() is ideal for replicating spring physics and bounce effects with exact control
  • Consider browser support--linear() is newer and may need fallbacks

For most web development projects, cubic-bezier() provides the best balance of flexibility and browser compatibility.

Linear Function Examples
1/* Creates ease-in-out-like behavior with segments */2.custom-ease {3 transition-timing-function: linear(4 0, 0.05, 0.2, 0.45, 0.7, 0.9, 15 );6}7 8/* Simulates spring physics */9.spring {10 animation: springIn 0.6s linear(11 0, 0.02, 0.05, 0.1, 0.15, 0.25,12 0.35, 0.45, 0.55, 0.65, 0.75,13 0.85, 0.95, 114 );15}

Applying Easing to CSS Properties

Easing functions work with both transitions and animations through specific properties.

transition-timing-function

Controls easing for CSS transitions when properties change state.

animation-timing-function

Controls easing for keyframe animations, either globally or per-keyframe.

Transition and Animation Properties
1/* Smooth hover with custom easing */2.button {3 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),4 opacity 0.2s ease-out;5}6 7/* Keyframe animation with easing */8@keyframes slideIn {9 0% {10 transform: translateX(-100%);11 animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);12 }13 60% {14 transform: translateX(10%);15 animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);16 }17 100% {18 transform: translateX(0);19 }20}21 22/* Per-property timing functions */23.card {24 transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),25 opacity 0.2s ease-out,26 background-color 0.3s ease;27}

Performance Best Practices

Optimize your animations for smooth 60fps performance with these techniques.

GPU Acceleration

Animate only transform and opacity properties for best performance (GPU-accelerated). These properties don't trigger layout recalculations.

Best Practices

  • Animate only transform and opacity for 60fps
  • Avoid animating width, height, margin, padding
  • Use will-change sparingly to hint browser optimization
  • Test on actual devices, not just development tools

Proper animation performance is a key aspect of professional web development that ensures smooth user experiences across all devices.

Performance Optimization Examples
1/* Good: GPU-accelerated properties */2.animate-good {3 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),4 opacity 0.3s ease;5}6 7/* Bad: Triggers layout recalculation */8.animate-bad {9 transition: width 0.3s ease,10 height 0.3s ease;11}12 13/* Create compositing layer */14.gpu-layer {15 transform: translateZ(0);16 will-change: transform;17}18 19/* Use translate instead of top/left */20.move-element {21 position: relative;22 transform: translateX(0);23 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);24}

Accessibility: Respecting Reduced Motion

Many users experience motion sensitivity (vestibular disorders). Respect their preferences by providing alternative animations.

Using prefers-reduced-motion

@media (prefers-reduced-motion: reduce) {
 .animated-element {
 transition: transform 0.1s ease;
 }
}

Key Considerations

  • Never disable all motion without user consent
  • Provide subtle or minimal animation for reduced motion preferences
  • Ensure information is not conveyed through motion alone
  • Test with motion disabled to verify functionality

Practical Code Examples

Real-world patterns you can use in your projects.

Button Hover Effects

.btn-primary {
 position: relative;
 transform: translateY(0);
 transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1),
 box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.btn-primary:hover {
 transform: translateY(-2px);
 box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.btn-primary:active {
 transform: translateY(0);
 transition: transform 0.1s ease;
}

Modal Animations

.modal-content {
 opacity: 0;
 transform: scale(0.95) translateY(10px);
 transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1),
 transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.modal-content.active {
 opacity: 1;
 transform: scale(1) translateY(0);
}

Staggered List Animations

.list-item {
 opacity: 0;
 transform: translateY(20px);
 transition: opacity 0.4s ease-out,
 transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.list-item.visible {
 opacity: 1;
 transform: translateY(0);
}

/* Stagger delays */
.list-item:nth-child(1) { transition-delay: 0ms; }
.list-item:nth-child(2) { transition-delay: 50ms; }
.list-item:nth-child(3) { transition-delay: 100ms; }

Quick Reference: Choosing the Right Easing

Animation TypeRecommended EasingExample
Modal dialogscubic-bezier(0.4, 0, 0.2, 1)Smooth, natural appearance
Button hoverscubic-bezier(0.4, 0, 0.2, 1)Subtle lift effect
Page transitionsease-in-outGradual start and end
Loading spinnerslinearConsistent rotation
Notification toastscubic-bezier(0.4, 0, 0.2, 1)Gentle appearance
Card selectionscubic-bezier(0.34, 1.56, 0.64, 1)Energetic feedback
Menu itemsease-outQuick open, slow close
Form inputseaseStandard focus effect

Ready to Build Polished, Performant Interfaces?

Master modern CSS techniques to create smooth, natural animations that delight users.