Skip to content

A CSS Animations Tutorial

New Course Coming Soon:

Get Really Good at Git

CSS Animations are a great way to create visual animations, not limited to a single movement like CSS Transitions, but much more articulated. An animation is applied to an element using the `animation` property

Introduction

An animation is applied to an element using the animation property.

.container {
  animation: spin 10s linear infinite;
}

spin is the name of the animation, which we need to define separately. We also tell CSS to make the animation last 10 seconds, perform it in a linear way (no acceleration or any difference in its speed) and to repeat it infinitely.

You must define how your animation works using keyframes. Example of an animation that rotates an item:

@keyframes spin {
  0% {
    transform: rotateZ(0);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

Inside the @keyframes definition you can have as many intermediate waypoints as you want.

In this case we instruct CSS to make the transform property to rotate the Z axis from 0 to 360 grades, completing the full loop.

You can use any CSS transform here.

Notice how this does not dictate anything about the temporal interval the animation should take. This is defined when you use it via animation.

A CSS Animations Example

I want to draw four circles, all with a starting point in common, all 90 degrees distant from each other.

<div class="container">
  <div class="circle one"></div>
  <div class="circle two"></div>
  <div class="circle three"></div>
  <div class="circle four"></div>
</div>
body {
  display: grid;
  place-items: center;
  height: 100vh;
}

.circle {
  border-radius: 50%;
  left: calc(50% - 6.25em);
  top: calc(50% - 12.5em);
  transform-origin: 50% 12.5em;
  width: 12.5em;
  height: 12.5em;
  position: absolute;
  box-shadow: 0 1em 2em rgba(0, 0, 0, 0.5);
}

.one,
.three {
  background: rgba(142, 92, 205, 0.75);
}

.two,
.four {
  background: rgba(236, 252, 100, 0.75);
}

.one {
  transform: rotateZ(0);
}

.two {
  transform: rotateZ(90deg);
}

.three {
  transform: rotateZ(180deg);
}

.four {
  transform: rotateZ(-90deg);
}

You can see them in this Glitch: https://glitch.com/edit/#!/flavio-css-circles

Let’s make this structure (all the circles together) rotate. To do this, we apply an animation on the container, and we define that animation as a 360 degrees rotation:

@keyframes spin {
  0% {
    transform: rotateZ(0);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

.container {
  animation: spin 10s linear infinite;
}

See it on https://glitch.com/edit/#!/flavio-css-animations-tutorial

You can add more keyframes to have funnier animations:

@keyframes spin {
  0% {
    transform: rotateZ(0);
  }
  25% {
    transform: rotateZ(30deg);
  }
  50% {
    transform: rotateZ(270deg);
  }
  75% {
    transform: rotateZ(180deg);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

See the example on https://glitch.com/edit/#!/flavio-css-animations-four-steps

The CSS animation properties

CSS animations offers a lot of different parameters you can tweak:

PropertyDescription
animation-namethe name of the animation, it references an animation created using @keyframes
animation-durationhow long the animation should last, in seconds
animation-timing-functionthe timing function used by the animation (common values: linear, ease). Default: ease
animation-delayoptional number of seconds to wait before starting the animation
animation-iteration-counthow many times the animation should be performed. Expects a number, or infinite. Default: 1
animation-directionthe direction of the animation. Can be normal, reverse, alternate or alternate-reverse. In the last 2, it alternates going forward and then backwards
animation-fill-modedefines how to style the element when the animation ends, after it finishes its iteration count number. none or backwards go back to the first keyframe styles. forwards and both use the style that’s set in the last keyframe
animation-play-stateif set to paused, it pauses the animation. Default is running

The animation property is a shorthand for all these properties, in this order:

.container {
  animation: name duration timing-function delay iteration-count direction
    fill-mode play-state;
}

This is the example we used above:

.container {
  animation: spin 10s linear infinite;
}

JavaScript events for CSS Animations

Using JavaScript you can listen for the following events:

Be careful with animationstart, because if the animation starts on page load, your JavaScript code is always executed after the CSS has been processed, so the animation is already started and you cannot intercept the event.

const container = document.querySelector('.container')
container.addEventListener(
  'animationstart',
  (e) => {
    //do something
  },
  false
)
container.addEventListener(
  'animationend',
  (e) => {
    //do something
  },
  false
)
container.addEventListener(
  'animationiteration',
  (e) => {
    //do something
  },
  false
)

Which Properties You Can Animate using CSS Animations

A lot! They are the same you can animate using CSS Transitions, too.

Here’s the full list:

Property
background
background-color
background-position
background-size
border
border-color
border-width
border-bottom
border-bottom-color
border-bottom-left-radius
border-bottom-right-radius
border-bottom-width
border-left
border-left-color
border-left-width
border-radius
border-right
border-right-color
border-right-width
border-spacing
border-top
border-top-color
border-top-left-radius
border-top-right-radius
border-top-width
bottom
box-shadow
caret-color
clip
color
column-count
column-gap
column-rule
column-rule-color
column-rule-width
column-width
columns
content
filter
flex
flex-basis
flex-grow
flex-shrink
font
font-size
font-size-adjust
font-stretch
font-weight
grid-area
grid-auto-columns
grid-auto-flow
grid-auto-rows
grid-column-end
grid-column-gap
grid-column-start
grid-column
grid-gap
grid-row-end
grid-row-gap
grid-row-start
grid-row
grid-template-areas
grid-template-columns
grid-template-rows
grid-template
grid
height
left
letter-spacing
line-height
margin
margin-bottom
margin-left
margin-right
margin-top
max-height
max-width
min-height
min-width
opacity
order
outline
outline-color
outline-offset
outline-width
padding
padding-bottom
padding-left
padding-right
padding-top
perspective
perspective-origin
quotes
right
tab-size
text-decoration
text-decoration-color
text-indent
text-shadow
top
transform.
vertical-align
visibility
width
word-spacing
z-index
Are you intimidated by Git? Can’t figure out merge vs rebase? Are you afraid of screwing up something any time you have to do something in Git? Do you rely on ChatGPT or random people’s answer on StackOverflow to fix your problems? Your coworkers are tired of explaining Git to you all the time? Git is something we all need to use, but few of us really master it. I created this course to improve your Git (and GitHub) knowledge at a radical level. A course that helps you feel less frustrated with Git. Launching Summer 2024. Join the waiting list!
→ Get my CSS Handbook
→ Read my CSS Tutorial on The Valley of Code

Here is how can I help you: