AI Workshop: learn to build apps with AI →
Animations: How to Create CSS Animations with Keyframes

Join the AI Workshop and learn to build real-world apps with AI. A hands-on, practical program to level up your skills.


CSS Animations let you create complex, multi-step animations using keyframes. Unlike transitions (which only animate between two states), animations can have multiple stages and run automatically.

Defining Keyframes

First, define the animation stages with @keyframes:

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

You can use from and to instead of 0% and 100%:

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Applying Animations

Apply the animation to an element using the animation property:

.spinner {
  animation: spin 2s linear infinite;
}

Animation Properties

PropertyDescription
animation-nameName of the @keyframes animation
animation-durationHow long one cycle takes
animation-timing-functionAcceleration curve
animation-delayWait before starting
animation-iteration-countHow many times to run
animation-directionPlay forwards, backwards, or alternate
animation-fill-modeStyles before/after animation
animation-play-stateRunning or paused

animation-iteration-count

.box {
  animation-iteration-count: 3;      /* Run 3 times */
  animation-iteration-count: infinite; /* Loop forever */
}

animation-direction

ValueDescription
normalPlay forwards (default)
reversePlay backwards
alternateForward, then backward
alternate-reverseBackward, then forward
.box {
  animation-direction: alternate;
}

animation-fill-mode

Controls what styles apply when the animation isn’t running:

ValueDescription
noneNo styles applied outside animation
forwardsKeep final keyframe styles
backwardsApply first keyframe during delay
bothApply both forwards and backwards
.box {
  animation-fill-mode: forwards;
}

animation-play-state

Pause or resume an animation:

.box {
  animation-play-state: paused;
}

.box:hover {
  animation-play-state: running;
}

Shorthand

.box {
  animation: name duration timing-function delay iteration-count direction fill-mode play-state;
}

Example:

.box {
  animation: bounce 1s ease-in-out 0s infinite alternate forwards;
}

Multiple Keyframe Stages

Create complex animations with multiple stages:

@keyframes bounce {
  0% {
    transform: translateY(0);
  }
  25% {
    transform: translateY(-30px);
  }
  50% {
    transform: translateY(0);
  }
  75% {
    transform: translateY(-15px);
  }
  100% {
    transform: translateY(0);
  }
}

Multiple Animations

Apply multiple animations to one element:

.box {
  animation:
    spin 2s linear infinite,
    pulse 1s ease-in-out infinite;
}

JavaScript Events

Listen for animation events in JavaScript:

const box = document.querySelector('.box')

box.addEventListener('animationstart', () => {
  console.log('Animation started')
})

box.addEventListener('animationend', () => {
  console.log('Animation ended')
})

box.addEventListener('animationiteration', () => {
  console.log('Animation iteration completed')
})

Example: Pulsing Button

@keyframes pulse {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.7);
  }
  70% {
    transform: scale(1.05);
    box-shadow: 0 0 0 10px rgba(52, 152, 219, 0);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
  }
}

.button {
  animation: pulse 2s ease infinite;
}

Performance Tips

  • Animate transform and opacity for best performance
  • Use will-change sparingly to hint at upcoming animations
  • Avoid animating properties that trigger layout recalculation

Lessons in this unit:

0: Introduction
1: How to Use CSS Transforms (2D and 3D)
2: How to Create Smooth CSS Transitions
3: ▶︎ How to Create CSS Animations with Keyframes
4: How to continuously rotate an image using CSS
5: Compare the options for Animations on the Web