CSS Animations

CSS animations allow an element's styles to change over time using one or more keyframes. Unlike a transition, an animation can define multiple stages, repeat automatically, run in different directions, and begin without a property change such as a hover state.

An animation is created by defining its stages with the @keyframes at-rule and applying that animation to an element with animation properties.

How Animations Work

A CSS animation has two main parts: a set of keyframes that describes the changing styles and animation properties that control how those keyframes are played.

@keyframes move-box {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(150px);
  }
}
.box {
  animation-name: move-box;
  animation-duration: 2s;
}

The move-box animation changes the element's transform from its starting position to a position 150 pixels along the x-axis over two seconds.

@keyframes Rule

The @keyframes at-rule defines the stages of an animation. Each keyframe specifies property values at a particular point during the animation.

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

The from keyword represents the beginning of the animation and is equivalent to 0%. The to keyword represents the end and is equivalent to 100%.

Percentage keyframes can define additional stages between the beginning and end.

@keyframes change-color {
  0% {
    background-color: #0088cc;
  }
  50% {
    background-color: #02bf57;
  }
  100% {
    background-color: #0088cc;
  }
}

animation-name

The animation-name property identifies the @keyframes animation that should be applied to an element.

@keyframes grow {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.25);
  }
}
.box {
  animation-name: grow;
}

The animation name used by the element must correspond to the name of the intended keyframes rule.

The initial value is none, which means no keyframes animation is applied.

animation-duration

The animation-duration property specifies how long one animation cycle takes to complete.

.box {
  animation-name: grow;
  animation-duration: 2s;
}

Duration values can use seconds or milliseconds.

.box {
  animation-duration: 750ms;
}

The initial duration is 0s. A positive duration is therefore normally needed to make the progression through the keyframes visible.

animation-timing-function

The animation-timing-function property controls how an animation progresses between keyframes.

.box {
  animation-timing-function: ease-in-out;
}
Value General Behavior
ease Uses acceleration and deceleration, ending more slowly.
linear Progresses at a constant rate.
ease-in Starts slowly and accelerates.
ease-out Starts quickly and slows toward the end.
ease-in-out Starts and ends slowly.

The initial timing function is ease. Functions such as cubic-bezier() and steps() provide additional control.

animation-delay

The animation-delay property specifies how long to wait before an animation begins.

.box {
  animation-name: grow;
  animation-duration: 2s;
  animation-delay: 1s;
}

The animation waits one second before beginning. The initial delay is 0s.

A negative delay starts the animation immediately but makes it appear as though it has already been running for the specified amount of time.

.box {
  animation-delay: -1s;
}

animation-iteration-count

The animation-iteration-count property specifies how many times an animation cycle should run.

.box {
  animation-iteration-count: 3;
}

The animation runs three times. The initial value is 1.

The infinite keyword causes the animation to repeat indefinitely.

.box {
  animation-iteration-count: infinite;
}

Continuously repeating animation should be used carefully because unnecessary or persistent motion can be distracting.

animation-direction

The animation-direction property controls the direction in which animation cycles play.

Value Behavior
normal Each cycle plays from the beginning to the end.
reverse Each cycle plays in reverse.
alternate Cycles alternate between forward and reverse.
alternate-reverse Cycles alternate, beginning in reverse.
.box {
  animation-direction: alternate;
}

Alternating direction is useful when an element should move smoothly between two states without jumping back to its starting point after each cycle.

animation-fill-mode

The animation-fill-mode property controls whether styles from the animation apply outside the time during which the animation is actively executing.

Value Behavior
none Does not apply keyframe styles before or after execution.
forwards Retains the styles determined by the animation's final relevant keyframe after it finishes.
backwards Applies the styles from the appropriate starting keyframe during the animation delay.
both Applies both forwards and backwards fill behavior.
.box {
  animation-fill-mode: forwards;
}

animation-play-state

The animation-play-state property controls whether an animation is running or paused.

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

In this example, moving the pointer over the element pauses the animation. When the pointer leaves, the animation continues from its paused position.

The two values are running and paused.

animation Shorthand

The animation shorthand can combine several animation properties into one declaration.

.box {
  animation: move-box 2s ease-in-out 0s infinite alternate;
}

This example specifies the animation name, duration, timing function, delay, iteration count, and direction.

Value Meaning
move-box Animation name
2s Duration
ease-in-out Timing function
0s Delay
infinite Iteration count
alternate Direction

When two time values are included, the first is the animation duration and the second is the animation delay.

Multiple Keyframes

An animation can have any number of intermediate keyframes between its starting and ending states.

@keyframes move-and-turn {
  0% {
    transform: translateX(0) rotate(0);
  }
  50% {
    transform: translateX(100px) rotate(90deg);
  }
  100% {
    transform: translateX(200px) rotate(180deg);
  }
}

The browser calculates the intermediate values between each pair of keyframes, creating a continuous animated sequence.

Percentage keyframes are particularly useful when an animation needs more than a simple beginning and ending state.

Multiple Animations

More than one animation can be applied to an element by separating animation definitions with commas.

.box {
  animation: move-box 2s ease infinite alternate,
             change-color 4s linear infinite;
}

The animations run on the same element. Each animation can have its own duration, timing function, delay, iteration count, and other settings.

When multiple animations affect the same property at the same time, their interaction can be more complex, so separate animations are often easiest to manage when they affect different properties.

Animations vs Transitions

CSS animations and transitions both create changes over time, but they are designed for different types of effects.

Feature Transitions Animations
Keyframes No Yes
Multiple stages Normally changes between two states Can define many stages
Automatic repetition No Yes
Can start without a state change No Yes
Common use Hover, focus, and state changes Multi-stage or repeating effects

A transition is often appropriate when an existing state change should occur gradually. An animation is useful when the effect needs its own sequence of keyframes or playback behavior.

Animation Practices

Animation can provide useful feedback and visual emphasis, but it should support the content rather than interfere with it.

Practice Purpose
Keep motion purposeful Avoids unnecessary visual distraction.
Use appropriate durations Keeps interface feedback responsive.
Avoid excessive repetition Prevents persistent motion from dominating the page.
Test intermediate keyframes Helps identify unexpected movement or property changes.
Support reduced motion Respects visitors who request less nonessential motion.

The prefers-reduced-motion media feature can be used to reduce or remove nonessential animation for visitors who have requested reduced motion.

@media (prefers-reduced-motion: reduce) {
  .box {
    animation: none;
  }
}

CSS Animation Example

The following example moves a box horizontally while changing its background color. The alternate direction makes each new cycle play in the opposite direction.

@keyframes move-box {
  0% {
    transform: translateX(0);
    background-color: #0088cc;
  }
  100% {
    transform: translateX(200px);
    background-color: #02bf57;
  }
}
.box {
  animation: move-box 2s ease-in-out infinite alternate;
}

Open the example in the editor and change the duration, timing function, iteration count, or transform distance. You can also add a 50% keyframe to create another stage in the animation.

Play in Editor