CSS Animation Tutorial: Complete Beginner’s Guide
This is a complete syntax guide and interactive CSS animation tutorial for beginners. Use it as a reference to learn the different parts of the CSS animation specification.
Browser performance has come a long way over the last 10 years. It used to be much more difficult to add interactive animations to web pages due to possible rendering and performance issues. But nowadays CSS animations can be used much more freely and the syntax is generally much easier to learn compared to CSS features like grid or flexbox.
There are several features that are part of the W3C’s CSS animation specification. Some are easier to use than others. This CSS keyframe animation tutorial walks through the entire syntax, including the various properties. I’m including interactive demos so you can understand what’s possible with CSS animations.
The @keyframes syntax
Every CSS animation consists of two parts: one or more animation-*
properties along with a set of animation keyframes defined using @keyframes
at rule. Let’s take a detailed look at what goes into the construction of a @keyframes
ruleset.
The syntax looks like this:
@keyframes moveObject {
0% {
transform: translateX(0);
}
50% {
transform: translateX(300px);
}
100% {
transform: translateX(300px) scale(1.5);
}
}
As shown here, the @keyframes
at-rule consists of three basic parts:
- the
@keyframes
Rule followed by a custom animation name - A series of curly brackets enclosing all keyframes
- One or more keyframes, each with a percentage, followed by a rule set surrounded by curly brackets
In this first example of our CSS animation tutorial, I defined my animation by name moveObject
. This can be any name, it is case sensitive and must be respected custom identifier Rules in CSS. This custom name must match the name used in animation-name
Property (will be discussed later).
In my example, you’ll notice that I used percentages to define each of the keyframes in my animation. If my animation contains keyframes that are the same 0%
and 100%
can I use the alternative from
and to
Keywords:
@keyframes moveObject {
from {
transform: translateX(0);
}
50% {
transform: translateX(300px);
}
to {
transform: translateX(300px) scale(1.5);
}
}
The following interactive CodePen uses the above syntax in a live example:
See the pen CSS animations: the @keyframes at rule by Louis Lazaris on CodePen.
In the demo I included a button that resets the animation. I’ll explain later why this is necessary. But for now, you should know that this animation contains three keyframes that represent steps in this animation sequence: the start, the 50% step, and the end (ie 0%, 50%, and 100%). Each of them uses what is called a keyframe selector along with curly brackets to define the properties in that step.
Some things to consider @keyframes
Syntax:
- You can arrange the keyframe rule sets in any order and the browser will still execute them in the order determined by their percentage
- You can omit the 0% and 100% keyframes and the browser will automatically determine them based on the existing styles on the animated element
- If there are duplicate keyframes with different rule sets (e.g. two keyframes for 20% with a different transform value), the browser uses the last one
- You can define multiple keyframes in a single keyframe selector with a comma:
10%, 30% { ... }
- the
!important
The keyword overrides all property values, so it should not be used on a property within a keyframe rule set
👉 Now that you have a good understanding of them @keyframes
In this CSS animation tutorial, let’s take a look at the different animation properties defined for the animated element.
The animation properties we will cover:
The animation-name property
As mentioned before, every CSS animation you create must have a name that is defined in the @keyframes
Syntax. This name must be the same name defined with the animation-name
Property.
Using the CSS from the previous demo, the syntax looks like this:
.box {
animation-name: moveObject;
}
Again, the custom name I defined must also exist as a name for a @keyframes
at rule – otherwise this name will do nothing. You can think of this as a function call into JavaScript. The function itself would be that @keyframes moveObject {}
Part of the code while the function call is animation-name: moveObject
.
Some things to consider animation-name
:
- The initial value for
animation-name
isnone
, which means no keyframes are active. This can be used as a sort of “toggle” to turn off an animation. - Your chosen name is case-sensitive and can contain letters, numbers, underscores, and hyphens.
- The first character in the name must be a letter or a hyphen, but only a single hyphen.
- The name cannot be a reserved word like
unset
,initial
orinherit
.
The animation-duration property
the animation-duration
The property defines, not surprisingly, the time it takes for an animation to run from start to finish once. This value can be specified in seconds or milliseconds as shown below:
.box {
animation-duration: 2s;
}
The above would be the equivalent of the following:
.box {
animation-duration: 2000ms;
}
You can see that… animation-duration
Property in action in the following CodePen demo. In this demo, you can choose how long you want the animation to last. Try entering different values in seconds or milliseconds and then use the Animate the Box button to run the animation.
See the pen CSS animations: the animation-duration property by Louis Lazaris on CodePen.
If you use a small number along with ms
for the device, you may not even notice movement. Try setting a higher number if using milliseconds.
Some notes on usage animation-duration
:
- Negative values are invalid
- The unit must be included even if the duration is set to
0s
(the initial value) - You can use fractional values (e.g.
0.8s
)
The animation-timing-function property
the animation-timing-function
, which is not as obvious in meaning as the previous two properties, is used to define the way in which the CSS animation progresses. That might not be the clearest explanation, but the syntax might help clarify.
The declaration looks like this:
.box {
animation-timing-function: linear;
}
This property accepts the following keyword values:
ease
(the initial value)ease-in
ease-out
ease-in-out
linear
step-start
step-end
Most values are relatively easy to understand by their names, but you can see how they differ with the following interactive demo:
See the pen CSS Animations: the keywords for the animation timing feature by Louis Lazaris on CodePen.
Use the select input to choose one of the seven keyword values. Note that the ease-*
Values facilitate animation in several ways. A linear value is consistent throughout.
the animation-timing-function
The property also accepts the following functions:
cubic-bezier()
– Takes four numeric values, separated by commas, as argumentssteps()
– Takes as arguments two values, a number and a “jump term”, separated by a comma
The keyword values step-start
and step-end
correspond to the values steps(1, jump-start)
and steps(1, jump-end)
or.
As for cubic-bezier()
the following interactive demo may help you to understand the function a little better:
See the pen CSS animations: the cube-bezier() function by Louis Lazaris on CodePen.
Note that in the demo you can set the four arguments in the cubic-bezier()
Function. Two of the arguments can be negative, and two are restricted to decimal values between 0 and 1. For a decent explanation of how these types of timing functions work, see This article or this interactive tool.
the steps()
The function, on the other hand, accepts two arguments:
- An integer representing equal “stops” along a single cycle of the animation.
- An optional keyword called “Jumpterm” that determines whether the animation “holds” at specified intervals.
Again, an interactive demo should help you understand how these jump terms work:
See the pen CSS animations: the steps() function by Louis Lazaris on CodePen.
Try selecting an integer along with a jump term (or try without a jump term) to see how different keywords with different integer values differ. Apparently negative integers are allowed, but I don’t see any difference between 0 and a negative value.
The animation-iteration-count property
In some cases you’ll be happy with an animation running once, but sometimes you’ll want an animation to run multiple times. the animation-iteration-count
property you can do this by accepting a positive number representing how many times to run the animation:
.box {
animation-iteration-count: 3;
}
The initial value for animation-iteration-count
is 1
But you can also use the keyword infinite
(self-explanatory) or use a fractional value. A fractional value partially performs the animation on the fractional run:
.box {
animation-iteration-count: 3.5;
}
The code above loops through the animation three and a half times. That is, three full iterations, followed by a final iteration that stops exactly halfway.
This property is most useful when used in conjunction with animation-direction
Property (discussed next) because an animation that only runs from the beginning isn’t very useful if it runs more than once.
You can try the following demo, which lets you choose a fractional value for the number of iterations so you can see the effect:
See the pen CSS animations: the animation-iteration-count property by Louis Lazaris on CodePen.
The animation-direction property
As mentioned above in this CSS animation tutorial, the animation-direction
Property works well in conjunction with animation-iteration-count
. the animation-direction
property you can specify in which direction the animation should be played. The syntax looks like this:
.box {
animation-direction: alternate;
}
You can set the value as one of four keywords:
normal
– The animation will play forward on the first iteration (default setting).reverse
– The animation plays backwards on the first iterationalternate
– The animation plays forward on the first iteration and then switches on subsequent iterationsalternate-reverse
– Same asalternate
but plays backwards on the first iteration
You can try the different values with different iteration counts using the interactive demo below:
See the pen CSS animations: the animation-direction property by Louis Lazaris on CodePen.
The animation-play-state property
the animation-play-state
property isn’t very useful in a static CSS environment, but can be useful when writing animations that are interactive via JavaScript or even CSS.
This property accepts two values: running
or paused
:
.box {
animation-direction: paused;
}
By default, any given animation is in the running state. But you can use JavaScript to toggle the value of the property. You could even use an interactive CSS feature like :hover
or :focus
to put the animation in a “paused” state, which essentially freezes the animation wherever it is in the current iteration.
The interactive demo below has an animation that runs indefinitely with two buttons to ‘pause’ and ‘resume’ the animation.
See the pen CSS animations: the animation-play-state property by Louis Lazaris on CodePen.
The animation-delay property
Some animations are designed to start animating immediately, while others could benefit from a slight delay before the first iteration. the animation-delay
property allows you to achieve this.
.box {
animation-delay: 4s;
}
Like other time-based values, you can set them animation-delay
to a value in seconds or milliseconds. You can also use fractional values.
It is important to note that the lag only occurs on the first iteration, not on every iteration. You can try this out with the interactive demo below:
See the pen CSS animations: the animation-delay property by Louis Lazaris on CodePen.
The demo gives you the ability to change both the iteration value and the delay, so you can see that the delay doesn’t affect subsequent iterations – only the first one.
An interesting way to use this property is as a negative value. For example, try using the above demo setting animation-delay
to -0.5s
. You’ll find that the negative delay works almost like stepping forward in a time machine – the animation starts halfway through rather than at the beginning.
The animation-fill-mode property
The last longhand property I’ll cover in this CSS animation tutorial is one I used in the previous demo. You’ll notice that the box stays where it is when the animation stops the last iteration. This is achieved with animation-fill-mode
.
.box {
animation-fill-mode: forwards;
}
This property determines how an animation applies styles to the target element before and after it runs. This is a bit hard to grasp conceptually, so I’ll cover the meaning of each value; You can then compare the values using the interactive demo.
This property accepts the following four keyword values:
none
– By default, no styles are applied before or after executionforwards
– Preserves all styles applied in the last keyframe of the animationbackwards
– More or less the opposite of the previous value, it keeps the styles applied to the animation once it starts running but before the animation startsboth
– Retains styles for bothforwards
andbackwards
The last demo in this CSS animation tutorial will make things a little clearer, but this one may take a lot of playing around before you really understand what it does and how it achieves it.
See the pen CSS animations: the animation-fill-mode property by Louis Lazaris on CodePen.
I’ve added all the demos for the sake of simplicity a single CodePen collection.
You’ll find that in the demo you can adjust the fill mode, delay, direction, and number of iterations, as all of these can affect the look and feel. Also, I added a different background color to the animated box in the first keyframe, which in turn helps make the blend mode values a bit clearer. If you still don’t quite understand how animation-fill-mode
works, you can check an older article I wrote that discussed animation-fill-mode
detailed.
The animation shorthand property
I’ve covered eight different properties in this beginner CSS animation tutorial, and I encourage you to use the long hand. This makes it easier for you to see the explicitly set values.
Once you have a good understanding of each of the properties, you have the ability to use them animation
shorthand property that allows you to define all longhand properties in a single declaration.
.box {
animation: moveObject 2s ease-in-out 3 reverse running 1.3s forwards;
}
Honestly, that’s a lot of information on one line. I would recommend using the shorthand when the declaration doesn’t include all the properties, but maybe only three or four of them.
When using shorthand, you can arrange the values in any order, but remember the following rules:
- The first value that defines the time is the
animation-duration
; each subsequent time value is theanimation-delay
. - If there is a conflict between a keyword and the
animation-name
the keyword value takes precedence if it appears first. - Any omitted values are reset to their initial state, as with any CSS shorthand property.
Apply multiple animations to a single element
One final feature to note is that you have the ability to apply multiple animations to a single object by separating the animations with commas.
Here is an example using the shorthand:
.box {
animation: moveObject 2s ease-in-out, fadeBox 3s linear;
}
Here I have defined two different animations associated with two different sets of keyframes, but applied to the same object. The same code could be written in longhand as:
.box {
animation-name: moveObject, fadeBox;
animation-duation: 2s, 3s;
animation-timing-function: ease-in-out, linear;
}
Notice that each property contains two values separated by commas. If so, the shorthand would almost certainly be easier to read and maintain.
Conclusion of this CSS animation tutorial
If you are a CSS beginner and this CSS animation tutorial was your first introduction to experimenting with moving content on web pages, I hope the lesson was comprehensive enough. Maybe you can even integrate yourself CSS variables with animations to make them even more powerful.
👉 One last warning: use animations in moderation and remember that some web users may be negatively affected by flashing colors and other fast-moving objects.
With practice, the syntax and concepts for creating CSS animations will stay with you and you’ll definitely benefit from playing around with the code in the various demos.