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.
