CSS animations tutorial

This article or chapter is incomplete and its contents need further attention. Some information may be missing or may be wrong, spelling and grammar may have to be improved, use your judgment!

Web technology tutorials series
Beginners

## Contents

* 1 Introduction
* 2 Simple CSS Examples
* 2.1 Simple color animation
* 2.2 Simple moving animation
* 2.3 Moving with easing in and out
* 2.4 Rotation
* 2.5 Animating more attributes in the same keyframes
* 3 Animation with some JavaScript
* 3.1 Start/stop an animation with JavaScript
* 3.2 Catch me
* 4 Links
* 4.1 Official
* 4.2 Repositories
* 4.3 Visual code generators
* 4.4 Tutorials and manuals

Learning goals

* Create simple CSS animations
* Stop/Start CSS animations with JavaScript

Prerequisites

* CSS tutorial

Level and target population

* Beginners

Teaching materials

* Are available through code pen (see below)

Remarks

* This tutorial is intended for non-computer students in fields that are technology intensive. For people who need less, there exist many easy CSS tutorials on the web. This text is intended for students who also must learn principles and who are willing to learn CSS by doing a project, looking at CSS code and online reference manuals.
* Ideally, a teacher also should assign a text formatting task, during or before assigning this tutorial for reading).

## Introduction[edit | edit source]

The CSS animations specification "describes a way for authors to animate the values of CSS properties over time, using keyframes. The behavior of these keyframe animations can be controlled by specifying their duration, number of repeats, and repeating behavior." (CSS Animations Level 1, W3C Working Draft, 30 November 2017).

Keyframes define different values for a single CSS attribute, e.g. background, left, top, width. The computer then will fill in all the values in between during the time of the animation.

Simple example defing what will happen to a div with class="ani".

CSS:

div.ani {
animation: mykeyframes 5s;

@keyframes mykeyframes {
from {background: blue;}
to {background: red;}

## Simple CSS Examples[edit | edit source]

Below are some simple CSS Example in increasing complexity. The principle is always the same:

* For HTML elements (identified by any kind of selector, e.g. an id or a class) define animation properties
* Define a `animation-name` if you plan to use keyframes
* `@keyframes` should define at least a "from" and "to", or "0%" and "100" states. For each of these set the value of one or more CSS properties.

### Simple color animation[edit | edit source]

This animation will last 10 seconds and will show a transition from blue to green to yellow and back to blue.

Source: The CSS suite from the CSS consortium. The code below and in CodePen has been slightly altered.

http://test.csswg.org/suites/css-animations-1_dev/nightly-unstable/html/animation-keyframes-001.htm

Codepen (for play and copy/paste): https://codepen.io/danielkschneider/pen/KoBWpV

CSS:

div.coloranim {
animation-name: sample;
animation-duration: 10s;
background-color: blue;
height: 100px;
width: 100px;

@keyframes sample {
from {     background-color: blue;    }
30% {      background-color: green;    }
65% {      background-color: yellow;    }
to {       background-color: blue;    }

HTML:

<p>
There is a filled blue square with 'Filler Text' when the page loads.
Color of the square gradully changes in order: BLUE to GREEN to YELLOW and back to BLUE in 10 seconds.

Try to add another keyframe for another color. Make the animation slower, then faster.
</p>
<div id="coloranim">I argue for a change<br>Now</div>

### Simple moving animation[edit | edit source]

This example shows a crawling rectangle animating its `left` property.

* Original (slightly changed): http://test.csswg.org/suites/css-animations-1_dev/nightly-unstable/html/animation-keyframes-003.htm

* Playground: https://codepen.io/danielkschneider/pen/dmjvOg

CSS:

div {
animation-name: anim_1;
animation-duration: 10s;

background-color: lightgreen;
height: 50px;
width: 200px;
position: relative;

@keyframes anim_1 {
from {
left: 250px;
animation-timing-function: linear;

50% {
left: 75px;
animation-timing-function: linear;

to {
left: 0px;

HTML:

<p>
Rectangle crawls from right to left with constant speed.
Try to make it move down at the same time. E.g. use CSS <code>top</code> attribute.
</p>
<div>Such a nice day for crawling</div>

### Moving with easing in and out[edit | edit source]

As above, but with some easing in/out. I.e. slow start, then normal animation, slow end.

* Original (slightly changed): http://test.csswg.org/suites/css-animations-1_dev/nightly-unstable/html/animation-timing-function-004.htm

* Playground: https://codepen.io/danielkschneider/pen/yKqMZz

CSS:

div#move-ease-1 {
animation-name: sample;
animation-duration: 5s;
animation-timing-function: ease-in-out;
border-radius: 30px;
padding: 20px 10px 10px 10px;
background-color: pink;
height: 60px;
width: 100px;
position: relative;

@keyframes sample {
from {
left: 5px;

to {
left: 500px;

HTML:

<p>
Square starts moving from left to right; initially the animation starts slow, gains acceleration in the middle and again slows down at the end.
</p>
<div id="move-ease-1">Let us ease in and out</div>

The default easing function can be changed but before doing so try cubic-bezier values.

### Rotation[edit | edit source]

This example shows how to create a rotation with `transform: rotate()`. In addition, we will repeat this animation 5 times using `animation-iteration-count`

* Original: DKS

* Playground: https://codepen.io/danielkschneider/pen/oqMWbK

CSS:

div#turn, div#turn2 {
animation-name: spin_1;
animation-duration: 5s;
animation-iteration-count: 5;
/* animation-iteration-count: infinite; */
border-radius: 30px;
padding: 20px 10px 10px 10px;
margin: 10px 10px 20px 10px;
background-color: pink;
height: 20px;
width: 100px;
position: relative;
left: 100px;

@keyframes spin_1 {
0% {
transform: rotate(0deg);

// setting 50% to 90deg makes this irregular
50% {
transform: rotate(90deg);

100% {
transform: rotate(360deg);

HTML:

<p>
Square will spin
</p>
<div id="turn">Let us spin</div>
<div id="turn2">Let us spin</div>

### Animating more attributes in the same keyframes[edit | edit source]

This example demonstrates that one can set more than a single property in a keyframe. You are not obliged to change the same properties in each keyframe.

* Original: DKS
* Playground: https://codepen.io/danielkschneider/pen/eMjWxa

CSS:

div.turn {
animation-name: spin_1;
animation-duration: 5s;
animation-iteration-count: 5;
/* animation-iteration-count: infinite; */
border-radius: 30px;
padding: 10px 10px 10px 10px;
margin: 20px 10px 20px 10px;
background-color: pink;
height: 20px;
width: 100px;
position: relative;
left: -100px;

@keyframes spin_1 {
0% {
transform: rotate(0deg);
left: -100px;

50% {
transform: rotate(180deg);
left: 300px;
background-color: red;

100% {
transform: rotate(360deg);
left: 600px;
background-color: blue;

HTML:

<p>
Square will spin and walk
</p>
<div class="turn">Let us spin</div>
<div class="turn">Let us spin</div>

## Animation with some JavaScript[edit | edit source]

### Start/stop an animation with JavaScript[edit | edit source]

* Original: DKS
* Playground: https://codepen.io/danielkschneider/pen/jzpGoe

This example shows how to start/stop an animation by modifying a CSS property with some JavaScript code.

Recall that CSS properties have different names in JavaScript. Here is how:

1. Remove the dash
2. Capitalise words

To access a CSS property from JS, use this syntax:

`objet.style.property_name`
In the example below: thing.style.animationPlayState

Example:

CSS attribute name = `animation-play-state `
JavaScript CSS property name: `animationPlayState `

In the CSS code below, also notice that we will play the animation in an endless loop using ` animation-iteration-count: infinite;`

CSS:

div#turn {
animation-name: spin_1;
animation-play-state: running;
animation-duration: 5s;
animation-iteration-count: infinite;
animation-direction: alternate;
border-radius: 30px;
padding: 10px 10px 10px 10px;
margin: 20px 10px 20px 10px;
background-color: pink;
height: 20px;
width: 100px;
position: relative;
left: 0px;

@keyframes spin_1 {
0% {
transform: rotate(0deg);
left: 0px;

50% {
transform: rotate(180deg);
left: 300px;
background-color: red;

100% {
transform: rotate(360deg);
left: 600px;
background-color: blue;

HTML:

<p>Square will spin and walk: <input value="Stop/Start this" type="button" id="btn">
</p>
<div id="turn">Let us run ! 🕷</div>

JavaScript:

document.getElementById("btn").onclick = changeAnim;

var is_running = true;
function changeAnim() {
// console.log("button pressed");
var thing = document.getElementById("turn");
if (is_running) {
thing.style.animationPlayState = "paused";
is_running = false;
} else {
thing.style.animationPlayState = "running";
is_running = true;

//Instead of complicated if-then-else we could have used a conditional

### Catch me[edit | edit source]

This example does the same thing as the previous, except that the button is now the thing that moves.

* Original: DKS

* Playground: https://codepen.io/danielkschneider/pen/rdrYYO

CSS:

div#turn {
animation-name: spin_1;
animation-play-state: running;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-direction: alternate;
border-radius: 30px;
padding: 10px 10px 10px 10px;
margin: 20px 10px 20px 10px;
background-color: pink;
height: 20px;
width: 100px;
position: relative;
left: -200px;

@keyframes spin_1 {
from {
transform: rotate(0deg);
left: -20px;

30% {
transform: rotate(30deg);
left: 200px;
background-color: red;

60% {
transform: rotate(60deg);
left: 400px;
background-color: red;

to {
transform: rotate(90deg);
left: 800px;
background-color: blue;

HTML:

<p>Square will spin and walk
<div id="turn" "move">Catch me 🕷</div>

JavaScript:

document.getElementById("turn").onclick = changeAnim;
var is_running = true;
function changeAnim() {
var thing = document.getElementById("turn");
console.log("button pressed" + " state before change=" + thing.style.animationPlayState);
if (is_running) {
thing.style.animationPlayState = "paused";
is_running = false;
} else {
thing.style.animationPlayState = "running";
is_running = true;

JavaScript: Just for the fun of it. The following does exactly same as the above and is a bit shorter

var thing2 = document.getElementById("turn");
thing2.onclick = changeAnim2;

function changeAnim2() {
console.log("button pressed on:" + thing2 + " state:" + thing2.style.animationPlayState);
thing2.style.animationPlayState == "paused"
? (thing2.style.animationPlayState = "running")
: (thing2.style.animationPlayState = "paused");

## Links[edit | edit source]

### Official[edit | edit source]

* CSS Animations Level 1 W3C Working Draft, 30 November 2017 (as of April 2018)
* HTML5 test suite

### Repositories[edit | edit source]

Code to copy and paste

* http://anicollection.github.io/ (table with many animations). Click on the eye to get the code.
* http://leaverou.github.io/animatable/ (table with many animations). Not the full code.

### Visual code generators[edit | edit source]

Create the animation in a visual interface, then copy and paste

* http://cssanimate.com

### Tutorials and manuals[edit | edit source]

* Using CSS animations (MDN)
* CSS Animations (W3C Schools)
* CSS animation-timing-function Property
* CSS @keyframes Rule