← Back to Home

How to Use Easing Functions for CSS Animations

Updated January 14, 2026
csseasinganimationtiming functionsjavascript

Using Easing Functions for CSS Animations

Easing functions control the rate of change in animations, creating natural motion.

Standard CSS Easing

/* Built-in timing functions */
transition: transform 1s ease;        /* Default */
transition: transform 1s ease-in;    /* Slow start */
transition: transform 1s ease-out;   /* Slow end */
transition: transform 1s ease-in-out; /* Slow start and end */
transition: transform 1s linear;     /* Constant speed */

Custom Easing in JavaScript

type EasingFunction = (t: number) => number;

export const Easing: Record<string, EasingFunction> = {
  // Linear - no easing
  linear: (t: number) => t,

  // Quad - quadratic easing
  easeInQuad: (t: number) => t * t,
  easeOutQuad: (t: number) => t * (2 - t),
  easeInOutQuad: (t: number) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,

  // Cubic - cubic easing
  easeInCubic: (t: number) => t * t * t,
  easeOutCubic: (t: number) => --t * t * t + 1,
  easeInOutCubic: (t: number) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,

  // Quart - quartic easing
  easeInQuart: (t: number) => t * t * t * t,
  easeOutQuart: (t: number) => 1 - --t * t * t * t,
  easeInOutQuart: (t: number) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t,

  // Quint - quintic easing
  easeInQuint: (t: number) => t * t * t * t * t,
  easeOutQuint: (t: number) => 1 + --t * t * t * t * t,
  easeInOutQuint: (t: number) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t,

  // Sine - sinusoidal easing
  easeInSine: (t: number) => -Math.cos(t * (Math.PI / 2)) + 1,
  easeOutSine: (t: number) => Math.sin(t * (Math.PI / 2)),
  easeInOutSine: (t: number) => -(Math.cos(Math.PI * t) - 1) / 2,
};

Usage in Animations

function animateValue(
  from: number,
  to: number,
  duration: number,
  easing: EasingFunction = Easing.linear,
  onUpdate: (value: number) => void
): void {
  const startTime = performance.now();

  function update(currentTime: number) {
    const elapsed = currentTime - startTime;
    const progress = Math.min(elapsed / duration, 1);
    const easedProgress = easing(progress);
    const value = from + (to - from) * easedProgress;

    onUpdate(value);

    if (progress < 1) {
      requestAnimationFrame(update);
    }
  }

  requestAnimationFrame(update);
}

Frame-Based Animation (Remotion)

function calculateWithEasing(
  frame: number,
  duration: number,
  easing: EasingFunction
): number {
  const progress = frame / duration;
  return easing(Math.min(Math.max(progress, 0), 1));
}

// Example: Fade in with ease-out
export const FadeIn: React.FC = () => {
  const frame = useCurrentFrame();
  const { durationInFrames } = useVideoConfig();
  const fadeInFrames = 30;

  const opacity = calculateWithEasing(
    Math.min(frame, fadeInFrames),
    fadeInFrames,
    Easing.easeOut
  );

  return <div style={{ opacity }} />;
};

Common Easing Patterns

Pattern Use Case Function
Ease Out Natural movement, exits easeOut, easeOutQuad
Ease In Anticipation, building up easeIn, easeInQuad
Ease In-Out Smooth back-and-forth easeInOut, easeInOutQuad
Linear Constant, mechanical linear

Visual Comparison

linear:     ━━━━━━━━━━━━━━━━━
easeIn:     ╱╲╱╲╱╲╱╲╱╲╱╲
easeOut:    ╲╱╲╱╲╱╲╱╲╱╲╱
easeInOut:  ╱‾‾‾‾‾‾‾‾‾╲

CSS Cubic Bezier

Custom easing curves using cubic-bezier:

/* ease-in-out = cubic-bezier(0.425, 0, 0.575, 1) */
transition: transform 1s cubic-bezier(0.425, 0, 0.575, 1);

/* Custom sharp ease-in */
transition: transform 1s cubic-bezier(0.9, 0, 1, 1);

/* Custom bounce */
transition: transform 1s cubic-bezier(0.68, -0.55, 0.265, 1.55);

Bezier to Function Conversion

function cubicBezier(p1x: number, p1y: number, p2x: number, p2y: number): EasingFunction {
  return (t: number) => {
    // Cubic bezier formula
    const u = 1 - t;
    return (
      3 * u * u * t * p1y +
      3 * u * t * t * p2y +
      t * t * t
    );
  };
}

// Usage
const customEase = cubicBezier(0.425, 0, 0.575, 1); // Similar to ease-in-out

Spring Easing

For springy, bouncy animations:

function springEasing(
  t: number,
  stiffness: number = 0.1,
  damping: number = 0.3
): number {
  const angularFreq = Math.sqrt(stiffness);
  const decay = damping * angularFreq;
  return 1 - Math.exp(-decay * t) * Math.cos(angularFreq * t);
}

Recommendations by Use Case

Animation Type Recommended Easing
Fade in/out easeOut, easeInOut
Slide in easeOutQuart
Scale/zoom easeInOut
Rotation easeInOutCubic
UI transitions easeOut (snappy)
Background motion linear (subtle)
Entrance easeOutBack (overshoot)
Exit easeIn (quick)