What Are CSS Easing Functions?

CSS easing functions define the rate of change of a property over time during an animation or transition. Instead of moving at a constant speed, elements can accelerate, decelerate, or even bounce — creating motion that feels natural and polished.

Think of easing like driving a car. You don't go from 0 to 60 instantly; you accelerate smoothly. Similarly, a UI element sliding into view feels much more professional when it eases in rather than jerking to a stop. The easing function visualizer on Wang Toolbox lets you compare all these curves side by side.

Built-In Easing Keywords

CSS provides five built-in keyword values that cover the most common easing patterns. They're the quickest way to add polish to any transition.

/* The five built-in easing keywords */
.element {
  transition: transform 0.3s ease;        /* Default - slow start, fast middle, slow end */
  transition: transform 0.3s linear;       /* Constant speed throughout */
  transition: transform 0.3s ease-in;      /* Starts slow, ends fast */
  transition: transform 0.3s ease-out;     /* Starts fast, ends slow */
  transition: transform 0.3s ease-in-out;  /* Slow start and end, fast middle */
}

The default ease keyword works well for most UI transitions like hover effects and menu animations. linear is useful for color transitions or progress bars where uniform motion is desired. ease-out is excellent for elements entering the viewport, while ease-in works well for exit animations.

Cubic Bézier: Total Control

For custom easing curves, CSS provides the cubic-bezier() function. It takes four parameters that define the control points of a cubic Bézier curve: cubic-bezier(x1, y1, x2, y2).

/* Custom cubic-bezier curves */
/* Bounce-like entrance */
.card {
  transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

/* Snappy, professional motion */
.sidebar {
  transition: transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
}

/* Smooth fade with overshoot */
.modal {
  transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

The built-in keywords are actually shortcuts for specific Bézier curves:

A y-value outside the 0-1 range creates bouncing or elastic effects. For example, a value greater than 1 overshoots the target, then settles back. Try experimenting with different control points in the easing function visualizer to see how each curve behaves in real time.

Step Timing for Discrete Animations

Not all animations need smooth interpolation. The steps() function divides the animation into equal discrete jumps — useful for sprite animations, typewriter effects, or any frame-based motion.

/* Step timing examples */
/* Typewriter effect - 10 equal steps */
.typewriter {
  overflow: hidden;
  white-space: nowrap;
  animation: typing 2s steps(10) forwards;
}

/* Sprite animation - jump between frames */
.sprite-run {
  width: 64px;
  height: 64px;
  background-image: url('run-sprite.png');
  animation: play-frames 0.6s steps(4) infinite;
}

@keyframes play-frames {
  from { background-position: 0 0; }
  to   { background-position: -256px 0; }
}

The step-start and step-end keywords are shorthand for steps(1, start) and steps(1, end), instantly jumping between states. Use these for toggle switches or visibility changes that shouldn't interpolate.

Bounce and Elastic Effects

For playful UI, you can simulate bounce and elastic motion using cubic-bezier curves with overshoot. These effects are great for attention-grabbing elements like notifications or badges.

/* Bounce and elastic cubic-bezier curves */

/* Springy bounce */
.notification-badge {
  animation: pop-in 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55) forwards;
}

/* Elastic overshoot */
.drag-handle {
  transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes pop-in {
  0%   { transform: scale(0); }
  100% { transform: scale(1); }
}

Use these sparingly — too many bouncy animations on one page feels chaotic. Reserve elastic curves for moments that genuinely benefit from extra visual weight.

How to Choose the Right Easing

Picking the right easing function depends on the context and the feeling you want to convey:

Duration is just as important as easing. Most UI animations should run between 200ms and 500ms — anything slower feels sluggish, and anything faster is barely noticeable. Mobile interfaces benefit from slightly shorter durations (150-300ms) to feel more responsive.

Ready to experiment with easing curves yourself? Try the easing function visualizer to compare all the curves discussed here, from built-in keywords to custom cubic-bezier functions. Visual feedback makes it much easier to understand how each curve behaves before you commit it to code.