CSS animation property
Learn about CSS animation property which is used to animate (gradually change from one style to another) CSS properties with discrete values. See examples.
The CSS animation property lets you animate elements — gradually changing one or more CSS values over time — without any JavaScript. It works on properties whose values can be interpolated, such as layout dimensions (border, height, width), position (left, top), font size, color and opacity.
This page covers the animation shorthand, all eight individual animation-* longhand properties, the @keyframes at-rule that drives them, how to run several animations at once, and how to respect users who prefer reduced motion. animation is one of the CSS3 properties.
An animation is built from two parts: a @keyframes rule that describes what the element looks like at points along the timeline, and the animation property (or its longhands) on the element that says how to play that timeline — how long, how many times, in which direction, and so on.
Legacy browsers may require the -webkit- prefix for older support.
Properties that use a keyword as a value, such as display: none; or visibility: hidden;, cannot be animated. Properties with values such as height: auto; also cannot be animated.
The @keyframes at-rule
To use animation you must first specify what should happen at specific moments during the animation. This is defined with the @keyframes at-rule.
The @keyframes rule consists of a keyword “@keyframes” followed by animation-name, which identifies the animation. The animation is then applied to an element by using this identifier as a value for the animation-name property.
In curly braces, we put keyframe selectors, which define keyframes (or waypoints) in the animation sequence when the styles should be changed. The keyframe selector can start with a percentage (%) or with the keywords “from” (same as 0%) and “to” (same as 100%). 0% is a starting point of the animation, 100% is the endpoint.
Example of animation with the @keyframe rule:
Example of the animation property with @keyframes
<!DOCTYPE html>
<html>
<head>
<style>
.element {
padding: 50px;
animation: pulse 4s infinite;
}
@keyframes pulse {
0% {
background-color: #8ebf42;
}
50% {
background-color: #1c87c9;
}
100% {
background-color: #d5dce8;
}
}
</style>
</head>
<body>
<div class="element">Background of this text is animated using CSS3 animation property.</div>
</body>
</html>In this example, we bind the animation to the <div> element. The animation will last for 4 seconds, and it will gradually change the background color of the <div> element from "green" to "grey".
Animation-related Properties
animation is the shorthand property for setting all the individual animation properties in a single declaration. The standard longhands are summarized below.
| Property | Sets | Common values |
|---|---|---|
animation-name | The @keyframes rule to play | a name, none |
animation-duration | How long one cycle lasts | 2s, 500ms (default 0s — no animation) |
animation-timing-function | The speed curve within each cycle | ease, linear, ease-in-out, cubic-bezier(…) |
animation-delay | Wait before starting | 1s, -2s (negative starts mid-animation) |
animation-iteration-count | How many times to play | a number, infinite |
animation-direction | Forward, reverse, or back-and-forth | normal, reverse, alternate |
animation-fill-mode | Styles before/after running | none, forwards, backwards, both |
animation-play-state | Whether it runs or pauses | running, paused |
Now let’s see animation-related properties in action.
Example of animation with some animation-related properties:
@keyframes pulse {
/* declare animation actions here */
}
.element {
animation-name: pulse;
animation-duration: 3.5s;
animation-timing-function: ease-in;
animation-delay: 1s;
animation-direction: alternate;
animation-iteration-count: infinite;
animation-fill-mode: none;
animation-play-state: running;
}
/*
The same can be declared using the animation shorthand property
*/
.element {
animation: pulse 3.5s ease-in 1s alternate infinite none running;
}The order of values in the shorthand is mostly flexible, with two rules to remember: the name must be present, and where both a duration and a delay appear, the first time value is the duration and the second is the delay. Any omitted value falls back to its default (for example, leaving out animation-iteration-count plays the animation once).
Animation-name
This property defines the name of the @keyframes rule you want to apply.
Syntax of animation-name property
animation-name: keyframe-name | none | initial | inheritExample of the animation-name property:
<!DOCTYPE html>
<html>
<head>
<style>
div {
padding: 50px;
animation: element 4s infinite;
}
@keyframes element {
0% {
background-color: #8ebf42;
}
50% {
background-color: #1c87c9;
}
100% {
background-color: #d5dce8;
}
}
</style>
</head>
<body>
<h2>Animation-name example</h2>
<div>The name of the animation is set as "element".</div>
</body>
</html>Animation-duration
It defines the length of time (in seconds or milliseconds) that animation takes to complete one cycle. If this property is not specified, the animation will not occur.
Syntax of animation-duration property
animation-duration: time | initial | inheritExample of the animation-duration property:
<!DOCTYPE html>
<html>
<head>
<style>
.element {
padding: 50px;
animation: pulse 7s infinite;
}
@keyframes pulse {
0% {
background-color: #8ebf42;
}
50% {
background-color: #1c87c9;
}
100% {
background-color: #eee
}
}
</style>
</head>
<body>
<div class="element">Background of this text is animated using CSS3 animation property</div>
</body>
</html>Animation-timing-function
This property defines how an animation will progress over the duration of each cycle — not throughout the whole of the animation.
Syntax of animation-timing-function property
animation-timing-function: linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier(n,n,n,n) | initial | inheritExample of the animation-timing-function property with the “ease” value:
<!DOCTYPE html>
<html>
<head>
<title>The title of the document</title>
<style>
div {
width: 100px;
height: 100px;
border-radius: 50%;
background: #1c87c9;
position: relative;
-webkit-animation: element 5s infinite;
/* Safari 4.0 - 8.0 */
-webkit-animation-timing-function: ease;
/* Safari 4.0 - 8.0 */
animation: element 5s infinite;
animation-timing-function: ease;
}
/* Safari 4.0 - 8.0 */
@-webkit-keyframes element {
from {
left: 0px;
}
to {
left: 200px;
}
}
@keyframes element {
from {
left: 0px;
}
to {
left: 200px;
}
}
</style>
</head>
<body>
<h2>Animation-timing-function example</h2>
<div></div>
</body>
</html>Animation-delay
This property sets the time (in seconds or milliseconds) between the element being loaded and the start of the animation.
Syntax of animation-delay property
animation-delay: time | initial | inheritExample of the animation-delay property:
Example of the CSS animation-delay property
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 120px;
height: 120px;
background: #1c87c9;
position: relative;
animation: delay 5s infinite;
animation-delay: 3s;
}
@keyframes delay {
from {
left: 0px;
}
to {
left: 300px;
}
}
</style>
</head>
<body>
<h2>Animation-delay example</h2>
<p>Here the animation starts after 3 seconds.</p>
<div></div>
</body>
</html>Animation-direction
It defines whether the animation should play in reverse on alternate cycles or not.
Syntax of animation-direction property
animation-direction: normal | reverse | alternate | alternate-reverse | initial | inheritThe following values can be applied:
- normal — (default) animation is played forward (keyframes 0% - 100%)
- reverse — animation is played backwards (keyframes 100% - 0%)
- alternate — the animation is played forward, then it is reversed and repeated.
- alternate-reverse — the animation is played backwards then forward.
Example of the animation-direction property:
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 120px;
height: 120px;
background: #ccc;
position: relative;
animation: myfirst 5s 1;
animation-direction: normal;
}
@keyframes myfirst {
0% {
background: #8DC3CF;
left: 0px;
top: 0px;
}
25% {
background: #1c87c9;
left: 200px;
top: 0px;
}
50% {
background: #030E10;
left: 200px;
top: 200px;
}
75% {
background: #666;
left: 0px;
top: 200px;
}
100% {
background: #8ebf42;
left: 0px;
top: 0px;
}
}
</style>
</head>
<body>
<h2>Animation-direction example</h2>
<p>Here the animation plays forwards.</p>
<div></div>
</body>
</html>Animation-iteration-count
Sets the number of times an animation cycle should be played before stopping. The default value is one, but any positive integer value can be set. If you set infinite keyword, the animation will be played endlessly.
A zero or negative integer will never play the animation.
Syntax of animation-iteration-count property
animation-iteration-count: number | infinite | initial | inheritExample of the animation-iteration-count property:
Example of the CSS animation-iteration-count property:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
html,
body {
margin: 0;
padding: 0;
}
div {
position: relative;
width: 100px;
height: 100px;
margin: 30px 0;
border-radius: 50%;
animation-name: pulse;
}
.element-one {
background-color: #1c87c9;
animation-duration: 3s;
animation-iteration-count: 3;
}
.element-two {
margin: 0;
background-color: #83bf42;
animation-duration: 5s;
animation-iteration-count: 2;
}
@keyframes pulse {
0% {
left: 0;
}
50% {
left: 50%;
}
100% {
left: 0;
}
}
</style>
</head>
<body>
<h2>The animation-iteration-count example</h2>
<p>The animation-iteration-count sets the number of times an animation cycle should be played before stopping.</p>
<div class="element-one"></div>
<div class="element-two"></div>
</body>
</html>Animation-fill-mode
This property specifies a style for the element applied before or after the animation is executed.
Syntax of animation-fill-mode property
animation-fill-mode: none | forwards | backwards | both | initial | inheritIt can assume the following values:
- forwards - specifies that the element should keep the style values set by the last keyframe (depends on animation-iteration-count and animation-direction properties).
- backwards - specifies that the element should get the style values set by the first keyframe (depends on animation-direction) and keep it within animation-delay period.
- both - specifies that the animation should follow the rules for both forwards and backwards.
- none - (default) specifies that no style will be applied to the element before or after the animation is executed
Example of the animation-fill-mode property with the “forwards” value:
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: #1c87c9;
position: relative;
-webkit-animation: element 5s;
/* Safari 4.0 - 8.0 */
-webkit-animation-fill-mode: forwards;
/* Safari 4.0 - 8.0 */
animation: element 5s;
animation-fill-mode: forwards;
}
/* Safari 4.0 - 8.0 */
@-webkit-keyframes element {
from {
top: 0px;
}
to {
top: 200px;
background-color: blue;
}
}
@keyframes element {
from {
top: 0px;
}
to {
top: 200px;
background-color: #8ebf42;
}
}
</style>
</head>
<body>
<h2>Animation-fill-mode example</h2>
<div></div>
</body>
</html>Animation-play-state
This property specifies whether the animation is playing or paused.
Syntax of animation-play-state property
animation-play-state: paused | running | initial | inheritThe default value is running.
Example of the animation-play-state property with the “running” value:
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 150px;
height: 150px;
background: #ccc;
position: relative;
animation: play 10s;
animation-play-state: running;
}
@keyframes play {
from {
left: 0px;
}
to {
left: 200px;
}
}
</style>
</head>
<body>
<h2>Animation-play-state example</h2>
<p>Here the animation-play-state is set to "running".</p>
<div></div>
</body>
</html>Multiple Animations
It is possible to declare multiple animations on a selector, you just need to separate the values with commas.
Example of multiple animations on a selector:
Example of The Animation Property Multiple Animations
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
height: 100%;
margin: 0;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.element {
height: 200px;
width: 200px;
background-color: #1c87c9;
animation: pulse 5s ease infinite alternate, nudge 5s linear infinite alternate;
}
@keyframes pulse {
0%,
100% {
background-color: #8ebf42;
}
50% {
background-color: #1c87c9;
}
}
@keyframes nudge {
0%,
100% {
transform: translate(0, 0);
}
50% {
transform: translate(150px, 0);
}
80% {
transform: translate(-150px, 0);
}
}
</style>
</head>
<body>
<div class="element"></div>
</body>
</html>Respecting reduced motion
Large or constant motion can trigger nausea, dizziness, or migraines for some users. Operating systems expose a "reduce motion" setting, and you can honor it with the prefers-reduced-motion media query — turning animations off (or toning them down) for those users while keeping them for everyone else.
.element {
animation: pulse 4s infinite;
}
@media (prefers-reduced-motion: reduce) {
.element {
animation: none;
}
}It is good practice to wrap any non-essential motion in this query so your animations stay accessible.
Common gotchas
- No
animation-durationmeans no animation. The default duration is0s, so the keyframes never get a chance to play. - Keyword and
autovalues don't animate. As noted above, properties likedisplay,visibility, andheight: autocan't be interpolated. Animateopacityandtransforminstead — they are also the most performant to animate. forwardsonly sticks if the iteration count is finite.animation-fill-mode: forwardsholds the last keyframe after the animation ends; withinfiniteit never ends, so there is nothing to hold.- Order matters for time values in the shorthand. The first
<time>is the duration, the second is the delay.
Related properties
- @keyframes — define the animation timeline.
- animation-name — choose which @keyframes rule to play.
- transition — animate between two states on a trigger such as
:hover. - transform — move, scale, and rotate elements (ideal to animate).