C

CSS Handbook

Clean • Professional

CSS Animations

7 minute

CSS Animations

CSS animations allow HTML elements to gradually change their styles over time. Instead of snapping instantly from one style to another, animations make transitions smooth and eye-catching.

With animations, you can:

  • Change multiple CSS properties at once (like color, size, or position).
  • Control how long an animation runs.
  • Decide if it repeats forever or just once.
  • Delay animations to start later.

To create an animation, you’ll need two main things:

  1. @keyframes rule – defines how the animation will behave.
  2. Animation properties – applied to an element to make the animation run.

The @keyframes Rule

Keyframes describe the stages of an animation. You can use from and to (start and end), or use percentages to create multiple steps.

Example 1: Simple color change

The <div> smoothly changes from red to yellow in 4 seconds.

<div class="box">Animate</div>
/* Keyframes: background changes from red → yellow */
    @keyframes myAnimation {
      from { background-color: red; }
      to   { background-color: yellow; }
    }

    /* Styling + applying animation */
    .box {
      width: 150px;
      height: 150px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      border-radius: 8px;

      /* Animation properties */
      animation-name: myAnimation;
      animation-duration: 4s;
      animation-timing-function: ease-in-out;
      animation-iteration-count: infinite; /* loops forever */
      animation-direction: alternate;      /* goes red→yellow then yellow→red */
    }

Example 2: Multi-step animation (percentages)

This box changes color multiple times within 4 seconds.

<div class="box">Animate</div>
/* Multi-step animation using percentages */
    @keyframes myAnimation {
      0%   { background-color: red; }
      25%  { background-color: yellow; }
      50%  { background-color: blue; }
      100% { background-color: green; }
    }

    .box {
      width: 150px;
      height: 150px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      color: white;
      border-radius: 8px;

      /* Apply animation */
      animation-name: myAnimation;
      animation-duration: 4s;
      animation-timing-function: linear;
      animation-iteration-count: infinite; /* keeps looping */
    }

Example 3: Moving + color animation

The box moves around while changing colors.

<div class="box">Animate</div>
/* Animation: moves in a square + changes color */
    @keyframes myAnimation {
      0%   { background-color: red;   left: 0px;   top: 0px; }
      25%  { background-color: yellow; left: 200px; top: 0px; }
      50%  { background-color: blue;   left: 200px; top: 200px; }
      75%  { background-color: green;  left: 0px;   top: 200px; }
      100% { background-color: red;   left: 0px;   top: 0px; }
    }

    .box {
      width: 100px;
      height: 100px;
      position: relative;  /* required for left/top to work */
      background-color: red;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      color: white;
      border-radius: 8px;

      /* Apply animation */
      animation-name: myAnimation;
      animation-duration: 4s;
      animation-timing-function: linear;
      animation-iteration-count: infinite;
    }

CSS Animation Properties

CSS animations are controlled by a set of properties that define how an element animates.

animation-name

Specifies which keyframes to use.

<div>Animation Name</div>
 /* Define keyframes */
    @keyframes myAnimation {
      from { background-color: red; }
      to   { background-color: yellow; }
    }

    /* Apply animation-name only */
    div {
      width: 150px;
      height: 150px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      border-radius: 8px;

      animation-name: myAnimation; /* only animation-name is set */
      animation-duration: 4s;      /* required for animation to run */
    }

animation-duration

Defines how long one cycle lasts.

<div>Animation Duration</div>
 /* Keyframes animation */
    @keyframes myAnimation {
      from { background-color: red; }
      to   { background-color: yellow; }
    }

    /* Apply animation */
    div {
      width: 150px;
      height: 150px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      border-radius: 8px;

      animation-name: myAnimation;    /* specifies the keyframes */
      animation-duration: 5s;         /* animation runs for 5 seconds */
      animation-iteration-count: infinite; /* optional: loop forever */
    }

animation-delay

Delays when the animation starts. Can also be negative (starts partway through).

 <div class="positive-delay"></div>
  <div class="negative-delay"></div>
/* Keyframes animation */
    @keyframes myAnimation {
      from { background-color: red; transform: translateX(0); }
      to   { background-color: yellow; transform: translateX(200px); }
    }

    /* Positive delay: waits 2s before starting */
    .positive-delay {
      width: 100px;
      height: 100px;
      display: inline-block;
      margin-right: 20px;
      animation-name: myAnimation;
      animation-duration: 4s;
      animation-delay: 2s;   /* Wait 2s before starting */
      animation-fill-mode: forwards;
    }

    /* Negative delay: starts as if already 2s in */
    .negative-delay {
      width: 100px;
      height: 100px;
      display: inline-block;
      animation-name: myAnimation;
      animation-duration: 4s;
      animation-delay: -2s;  /* Starts 2s into the animation */
      animation-fill-mode: forwards;
    }

animation-iteration-count

Sets how many times the animation runs.

<div class="three-times"></div>
  <div class="infinite"></div>
/* Keyframes animation */
    @keyframes myAnimation {
      from { background-color: red; transform: translateX(0); }
      to   { background-color: yellow; transform: translateX(200px); }
    }

    /* Runs 3 times */
    .three-times {
      width: 100px;
      height: 100px;
      margin-right: 20px;
      display: inline-block;
      animation-name: myAnimation;
      animation-duration: 2s;
      animation-iteration-count: 2;  /* Runs 3 times */
      animation-fill-mode: forwards;
    }

    /* Runs forever */
    .infinite {
      width: 100px;
      height: 100px;
      display: inline-block;
      animation-name: myAnimation;
      animation-duration: 2s;
      animation-iteration-count: infinite;  /* Runs forever */
      animation-fill-mode: forwards;
    }

animation-direction

Controls the playback direction.

  • normal → default (0% → 100%)
  • reverse → backwards (100% → 0%)
  • alternate → forward then backward
  • alternate-reverse → backward then forward
 <div class="alternate">animation-direction</div>
/* Keyframes animation */
    @keyframes myAnimation {
      from { background-color: red; transform: translateX(0); }
      to   { background-color: yellow; transform: translateX(200px); }
    }

    /* Animate forward then backward */
    .alternate {
      width: 100px;
      height: 100px;
      display: inline-block;
      animation-name: myAnimation;
      animation-duration: 2s;
      animation-iteration-count: infinite;  /* loops forever */
      animation-direction: alternate;       /* forward then backward */
      animation-fill-mode: forwards;
    }

animation-timing-function

Controls speed curve of the animation.

  • linear → constant speed
  • ease → slow → fast → slow
  • ease-in → slow start
  • ease-out → slow end
  • ease-in-out → slow start & end
  • cubic-bezier(n,n,n,n) → custom curve
 <div class="ease-in-out">animation-timing-function</div>
/* Keyframes animation */
    @keyframes myAnimation {
      from { transform: translateX(0); background-color: red; }
      to   { transform: translateX(300px); background-color: yellow; }
    }

    /* Apply ease-in-out timing */
    .ease-in-out {
      width: 100px;
      height: 100px;
      display: inline-block;
      color: white;
      display: flex;
      align-items: center;
      text-align: center ;
      justify-content: center;
      font-weight: bold;
      border-radius: 8px;

      animation-name: myAnimation;
      animation-duration: 3s;
      animation-iteration-count: infinite;
      animation-timing-function: ease-in-out; /* slow start & end */
    }

animation-fill-mode

Defines style applied before and/or after the animation.

  • none → default, no styles retained
  • forwards → keep last keyframe after animation ends
  • backwards → apply first keyframe during delay
  • both → apply both forwards & backwards
<div class="forwards">animation-fill-mode</div>
/* Keyframes animation */
    @keyframes myAnimation {
      from { transform: translateX(0); background-color: red; }
      to   { transform: translateX(300px); background-color: yellow; }
    }

    /* Apply forwards fill mode */
    .forwards {
      width: 100px;
      height: 100px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      border-radius: 8px;

      animation-name: myAnimation;
      animation-duration: 3s;
      animation-fill-mode: forwards; /* retains final keyframe after finishing */
    }

animation-play-state

Controls pause/play of the animation.

<div class="box">Animation-play-state</div>
  /* Keyframes animation */
    @keyframes myAnimation {
      from { transform: translateX(0); background-color: red; }
      to   { transform: translateX(300px); background-color: yellow; }
    }

    /* Animated box */
    .box {
      width: 100px;
      height: 100px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      border-radius: 8px;

      animation-name: myAnimation;
      animation-duration: 4s;
      animation-iteration-count: infinite;
      animation-play-state: play; /* plays by default */
      transition: background-color 0.3s;
    }

    /* Pause animation on hover */
    .box:hover {
      animation-play-state: paused; /* pauses when mouse is over */
    }

Shorthand animation Property

Combine all properties in a single line:

<div class="box">Shorthand animation Property</div>
    /* Keyframes animation */
    @keyframes myAnimation {
      0%   { transform: translateX(0); background-color: red; }
      50%  { transform: translateX(200px); background-color: blue; }
      100% { transform: translateX(0); background-color: green; }
    }

    /* Apply animation shorthand */
    .box {
      width: 100px;
      height: 100px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      border-radius: 8px;

      animation: myAnimation 3s linear 2s infinite alternate forwards;
      /* shorthand order:
         name duration timing-function delay iteration-count direction fill-mode
      */
    }

Real-Life Example: Bouncing Ball

The circle moves up and down endlessly, like a bouncing ball!

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Bouncing Ball</title>
  <style>
    body {
      height: 300px; /* ensures the ball has space to move */
      display: flex;
      align-items: flex-start;
      justify-content: center;
      margin: 0;
      padding: 20px;
    }

    @keyframes bounce {
      0%, 100% { top: 0; }
      50% { top: 200px; }
    }

    .ball {
      width: 50px;
      height: 50px;
      background: tomato;
      border-radius: 50%;
      position: relative;
      animation: bounce 2s ease-in-out infinite;
    }
  </style>
</head>
<body>
  <div class="ball"></div>
</body>
</html>

Quick Reference: CSS Animation Properties

PropertyDescription
@keyframesDefines the animation steps
animationShorthand for all animation properties
animation-nameName of the keyframes animation
animation-durationDuration of one cycle
animation-delayStart delay
animation-iteration-countNumber of times it runs
animation-directionPlay direction
animation-timing-functionSpeed curve
animation-fill-modeStyles applied before/after animation
animation-play-stateRunning or paused


Article 0 of 0