Skip to content
intermediate Phase 3 · CSS Advanced

CSS Animations & Transitions

Create smooth animations and transitions with CSS keyframes, transforms, and the Web Animations API.

1h
0 problems
Topic Progress 0%

Introduction

CSS Animations & Transitions

CSS animations and transitions bring interfaces to life by smoothly interpolating property values over time. While transitions handle simple state-to-state changes, keyframe animations unlock multi-step, looping, and highly choreographed motion sequences.

Key Concepts

  • Transitions interpolate between two states triggered by a change (hover, class toggle, media query).
  • Keyframe animations define named sequences of property snapshots that can loop, reverse, and delay independently of user triggers.
  • Transforms (translate, rotate, scale, skew) are the foundation of performant motion because they operate on the compositor layer without triggering layout or paint.
  • The Web Animations API gives JavaScript direct control over animation playback, enabling sequencing, pausing, seeking, and event-driven choreography that pure CSS cannot achieve.

Why It Matters

Motion communicates spatial relationships, draws attention to interactive elements, and provides feedback that makes an interface feel responsive. Mastering both CSS and JS animation tools lets you choose the simplest, most performant approach for each scenario.

Keyframe Animations

Keyframe Animations

Keyframe animations let you define a named sequence of styles at specific percentages along a timeline, then apply that sequence to any element.

Defining @keyframes

@keyframes slideIn {
  0% {
    transform: translateX(-100%);
    opacity: 0;
  }
  60% {
    transform: translateX(8%);
    opacity: 1;
  }
  100% {
    transform: translateX(0);
  }
}

Applying the Animation

.card {
  animation: slideIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

Animation Shorthand Properties

Property Purpose Example Values
animation-name References the @keyframes rule slideIn, pulse
animation-duration Total length of one cycle 0.3s, 500ms
animation-timing-function Easing curve ease-in-out, cubic-bezier(0.4, 0, 0.2, 1)
animation-delay Wait before starting 0.2s
animation-iteration-count How many times to run 1, infinite
animation-direction Normal, reverse, or alternating alternate
animation-fill-mode Style before/after running forwards, both
animation-play-state Pause or resume running, paused

Multi-Step Choreography

You can chain multiple property changes across percentages to create bounce, elastic, or staggered effects:

@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  40% { transform: translateY(-30px); }
  60% { transform: translateY(-15px); }
}

CSS Transitions

CSS Transitions

Transitions are the simplest way to animate property changes. When a computed style value changes—whether from a :hover pseudo-class, a class toggle via JavaScript, or a media query—the browser smoothly interpolates from the old value to the new value over a specified duration.

Transition Properties

.button {
  background-color: #3b82f6;
  color: white;
  transform: scale(1);
  transition: background-color 0.2s ease,
              transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.button:hover {
  background-color: #2563eb;
  transform: scale(1.05);
}

.button:active {
  transform: scale(0.97);
}

Timing Functions

The transition-timing-function controls the acceleration curve:

  • linear — constant speed
  • ease — slow start and end (default)
  • ease-in — slow start
  • ease-out — slow end
  • ease-in-out — slow start and end
  • cubic-bezier(x1, y1, x2, y2) — custom curve

Transition vs Animation

Use transitions when you need a simple two-state change tied to a user interaction. Use animations when you need looping, multi-step sequences, or effects that should run without a trigger.

Performance Tip

Only animate transform and opacity for 60fps performance. Animating width, height, top, left, or margin triggers layout recalculation on every frame, which is expensive.

CSS Transforms

CSS Transforms

Transforms modify the coordinate space of an element without affecting surrounding layout. They are the backbone of performant CSS motion because the browser can handle them entirely on the GPU compositor thread.

2D Transforms

.icon {
  transform: rotate(45deg) scale(1.2) translateX(10px);
}
  • translate(x, y) — repositions the element
  • rotate(angle) — rotates around the center
  • scale(sx, sy) — resizes the element
  • skew(ax, ay) — shears the element

3D Transforms

.card {
  transform-style: preserve-3d;
  perspective: 800px;
  transform: rotateY(15deg) translateZ(20px);
}
  • perspective(distance) — sets the vanishing point distance
  • rotateX(), rotateY(), rotateZ() — rotations around each axis
  • translateZ() — moves along the depth axis
  • scaleZ() — scales depth

Transform Origin

The default transform origin is 50% 50% 0 (center). Changing it affects the pivot point:

.door {
  transform-origin: left center;
  transform: rotateY(90deg);
}

Combining Transforms with Transitions

.button {
  transform: scale(1) rotate(0deg);
  transition: transform 0.25s ease-out;
}
.button:hover {
  transform: scale(1.08) rotate(-2deg);
}

Because transforms are composited on the GPU, this is fully hardware-accelerated and will not cause layout reflows.

The Web Animations API

The Web Animations API

The Web Animations API exposes animation playback from JavaScript, giving you imperative control that CSS alone cannot provide—sequencing, pausing, seeking, playback rate control, and animation event callbacks.

Creating an Animation

const element = document.querySelector('.box');
const animation = element.animate(
  [
    { transform: 'translateX(0)', opacity: 0 },
    { transform: 'translateX(100px)', opacity: 1 }
  ],
  {
    duration: 500,
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)',
    fill: 'forwards'
  }
);

Playback Control

animation.pause();
animation.play();
animation.reverse();
animation.playbackRate = 0.5; // half speed
animation.currentTime = 250; // seek to midpoint

Event Listeners

animation.onfinish = () => console.log('done');
animation.oncancel = () => console.log('cancelled');

When to Use the API

  • Sequencing — Chain multiple animations with precise timing using Promise-based finished property.
await animation1.finished;
animation2.play();
  • Dynamic input — Adjust playback rate or seek position based on scroll position or pointer movement.

  • Complex state machines — Pause, resume, and reverse animations based on application state.

Browser Support

The Web Animations API is supported in all modern browsers. For older browsers, the web-animations-js polyfill provides a compatible fallback.

Quiz

1. Which CSS properties trigger layout recalculation when animated, making them unsuitable for smooth 60fps transitions?

Question 1 options

2. What does the `animation-fill-mode: forwards` declaration do?

Question 2 options

3. In the Web Animations API, how do you chain two animations so the second starts only after the first finishes?

Question 3 options

Flashcards

Question

What is the difference between a CSS transition and a CSS keyframe animation?

Answer

A transition interpolates between two states triggered by a property change (hover, class toggle). A keyframe animation defines a named sequence of multiple property snapshots at percentage offsets that can loop, reverse, and run without a trigger.

Question

Why should you animate transform and opacity instead of width or top?

Answer

Transform and opacity are compositor-layer properties the GPU can animate without triggering layout reflow or paint. Animating width, height, top, or left forces the browser to recalculate layout on every frame, causing jank and dropped frames.

Question

What does the animation-fill-mode property control?

Answer

It determines whether the element retains computed styles before the animation starts (backwards), after it ends (forwards), or both. By default elements snap to their pre-animation state, so fill-mode: forwards or both is needed to preserve the animated result.

Revision Notes

Key Takeaways

  • 1. Use CSS transitions for simple two-state changes (hover, focus, active). Use @keyframes for multi-step, looping, or auto-playing animations.
  • 2. Always prefer animating transform and opacity for 60fps performance. These properties avoid layout recalculation and are handled entirely on the GPU compositor thread.
  • 3. The animation shorthand combines name, duration, timing-function, delay, iteration-count, direction, fill-mode, and play-state into a single readable declaration.
  • 4. The Web Animations API provides imperative JavaScript control—play, pause, reverse, seek, and playback rate adjustment—making it ideal for complex sequencing and dynamic input-driven motion.

Interview Tips

  • Explain the difference between transform and layout-triggering properties like top or width when discussing animation performance.
  • Describe how you would stagger multiple element animations (e.g., list items fading in sequentially) using animation-delay.
  • Know when to choose the Web Animations API over CSS: programmatic control, scroll-driven timing, or complex state machines.
  • Discuss the animation-fill-mode values (none, forwards, backwards, both) and when each is appropriate.

Cheat Sheet

TRANSITIONS: transition: property duration timing delay; — interpolates between two states. KEYFRAMES: @keyframes name { 0% { ... } 100% { ... } } — multi-step sequences. PERFORMANCE: animate transform and opacity only. TIMING: ease, linear, ease-in-out, cubic-bezier(x1,y1,x2,y2). FILL-MODE: forwards retains end state, backwards applies start state before delay. WEB ANIMATIONS API: element.animate(keyframes, options) returns an Animation object with play(), pause(), reverse(), currentTime, and finished Promise.