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:

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 is none, 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, initialor inherit.

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.

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:

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 arguments
  • steps() – 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:

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:

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:

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 iteration
  • alternate – The animation plays forward on the first iteration and then switches on subsequent iterations
  • alternate-reverse – Same as alternate but plays backwards on the first iteration

You can try the different values ​​with different iteration counts using the interactive demo below:

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.

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:

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 execution
  • forwards – Preserves all styles applied in the last keyframe of the animation
  • backwards – 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 starts
  • both – Retains styles for both forwards and backwards

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.

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 the animation-delay.
  • If there is a conflict between a keyword and the animation-namethe 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights