CSS Animations and Transitions
Tags: beginners, css
Published: 2019-12-07 11:48:44

---
title: CSS Animations and Transitions
published: true
description: A beginners guide to CSS Animations and Transitions
tags: beginners, css
series: FrontEnd Development Zero to Hero
---
In the early days of the web HTML was at its humble beginnings then CSS came around and it allow web developers to add effects like color and changing text font sizes. Fast forward to the year 1995 _JavaScript_ was invented and it opened the door for developers to add dynamic effects to a web page like _Animations_ and _Popups_. The latter was heavily misused for advertisement purposes and gaining user attention.

Years passed by and _JavaScript_ was the _de  facto_ technology for adding animations to HTML elements and developers who did not know how to program can seek the help of a _JavaScript_ programmer to complete some part of their project that require stuff like animations.

The dependency on JavaScript for adding animations and transitions reduced when animations and transitions was added natively to CSS specifically CSS3. CSS3 technologies are set of modules and you should not be surprised that [animations](https://www.w3.org/TR/css-animations-1/) and [transitions](https://www.w3.org/TR/css-transitions-1/) each have their own specifications.

With CSS animations you can move page element around, change color based on user interaction and with transitions you can change property values over a specified duration all without _JavaScript_.

_The following HTML and CSS will be used with slight modifications along the way. Please save them and make sure the CSS is linked with the HTML._

```html
<div class="parent">
  <div class="box"></div>
</div>
```
```css
.parent {
  width: 70%;
  outline: 5px solid #dddddd;
  margin: 0 auto;
  height: 500px;
}
```

_And kindly note that all screenshots are from <b>Firefox 70</b> web browser and its Developer Tools_.

<hr>

When starting out with CSS animations there is a particular technical term that we need to familiarize oursleves with and that is _keyframes_. Keyframes make animation possible.

From [the specification](https://www.w3.org/TR/css-animations-1/#keyframes) (emphasis mine):

>  __Keyframes are used to specify the values for the animating properties at various points during the animation__ . The keyframes specify the behavior of one cycle of the animation; the animation may iterate zero or more times.

That's pretty straight forward, but now the question is: How can we translate this theoretical definition to code? To answer this question we will have to know how keyframes are  specified.

The [specification](https://www.w3.org/TR/css-animations-1/#at-ruledef-keyframes) states:

> Keyframes are specified using the `@keyframes` at-rule

After the `@keyframes` at rule three things have to included:

* the _keyframes name_
* the _keyframe block_
* the _keyframe selector_

###__the keyframes name__

The _keyframes name_ is the name of the animation and it can be a [_custom indent_](https://www.w3.org/TR/css-values-4/#identifier-value) or a _string_ and the name is  _case sensitive_.

###__the keyframe block__

This is the block that will contain code that specify how the animation will behave.

###__the keyframe selector__

This specify the starting and ending position of the animation using a combination of `from` and `to` keyword or comma-separated list of percentage values.

All these can be summed up in the code snippet below:

```css
@keyframes <keyframes name> {

  /* We are inside the keyframe block */

  /*
   * The from and to code blocks are the keyframe
   * selectors
  */ 
  from {
    /* code here*/
  }

  to {
    /* code here*/
  }

  /*
   * Another alternative is to use comma-seprated
   * percentage values
  */
  0%,20% {
     /* code here */
  }

  20%,70% {
     /* code here */
  }

  70%,100% {
     /* code here */
  }

}
```

If you declare multiple `@keyframes` rules with the same name (i.e the animation name), the _cascade_ comes into effect and the last one in the document order wins, while all preceding ones are ignored.

<hr>

Keyframes is just part of the picture when it comes to creating animations in CSS and some properties ensure that it works as expected. They are:

* `animation-name`
* `animation-duration`
* `animation-delay`
* `animation-iteration-count`
* `animation-direction`
* `animation-timing-function`
* `animation-fill-mode`
* `animation-play-state`
* `animation`

These properties are bound to the element that you wish to animate.

```css
div {
  /* All animation for the div element will be here */
}
```

Now, let's discuss these properties in detail.

###__`animation-name`__
This is the name of the `@keyframes` at-rule that decsribe the animation keyframes.

Update the `.box` with an animation name, we'll call it _slide_:

```css
.box {
 /* All other properties remain the same */
 
 /*
  * "slide" will be the name given to our animation
 */
 animation-name: slide;
}
```

###__`animation-duration`__

The `animation-duration` property defines how long an animation would take to complete one cycle.

We'll make the animation last for `5s` for simplicity.

```css
.box {
 /* All other properties remain the same */
 
 animation-duration: 5s;
}
```

With these two properties in play we can animate the box by setting up a keyframe using the `@keyframe` at rule.

The keyframe below will move the box from its current location until the `top` offset property is `300px` and the `left` offset property is `250px`.

```css
@keyframes slide {

  from {
    top: 0;      /* The box current */
    left: 0;     /* location */
  }

  to {
    top: 300px;  /* The box location */
    left: 250px; /* during animation */
  }
	
}
```

Save and refresh your browser. You will realize the box _will not move_. Can you guess why?

When we talked about [CSS positioning](https://dev.to/ziizium/css-positioning-34d8) we made it clear that offset properties like `top`,`left` have no effect on an element with its `position`property set to `static`.

Use "Inspect Element" on the box and you can confirm this in the _Developer Tools_.

![A tomato colored box on a white background](https://thepracticaldev.s3.amazonaws.com/i/8098kiyg0rzbma2vzq47.PNG)

A simple `position: relative` applied to the `box` will fix this issue.

```css
.box {
 /* All other properties remain the same */
 
 position: relative;
}
```

Go ahead and save the file and refresh the browser, the box will now move as expected. You can also check the __Animation__ tab in the browser _Developer Tools_ to note details of the animation.

![A tomato colored box on a white background](https://thepracticaldev.s3.amazonaws.com/i/hz6zzceimkyzlml2zpqq.PNG)

<!-- exp here -->
###__`animation-delay`__

This specify the delay before an animation starts. This is as simple as its name.

Update your code:

```css
.box {
 /* All other properties remain the same */
 
 animation-delay: 3s;
}
```

Save and refresh your browser, the animation will start after _three seconds_.

###__`animation-iteration-count`__

By default the animation will run just once, using `animation-iteration-count` we can specify the number of times an animation should run.

```css
.box {
 /* All other properties remain the same */
 
 animation-iteration-count: 3;
}
```

The total execution time of this animation will be `18s` because the `animation-duration` is `5s` and the animation will run _three times_ which gives us:

* _3 * 15_ = _15s_

Added to the `animation-delay` of `3s` we get:

* _15s + 3_ = _18s_

You can confirm this in the _Developer Tools_ after the animation execution.

![A tomato colored box on a white background](https://thepracticaldev.s3.amazonaws.com/i/navftlm7i2jwwt1ywn6u.PNG)

###__`animation-direction`__

As the name implies the `animation-direction` determines the direction of the animation which can be any of the following:

* `normal` - This is the default and the animation played as normal (forwards)
* `reverse` - The animation is played in reverse direction
* `alternate` - This combine the behavior of `normal` and `reverse` and the animation is played forwards first and then backwards
* `alternate-reverse`  - This is opposite of `alternate` and the animation is played backwards first then forwards

The effect of this property is _really cool_. _If you want you can delete_ the `animation-delay` property just to speed things up.

```css
.box {
 /* All other properties remain the same */
 
 animation-direction: alternate;
}
```

Save and refresh your browser.

<!-- or take a look at the sandbox. -->

You should experiment with the remaining values.

###__`animation-timing-function`__
From the [specification](https://www.w3.org/TR/css-animations-1/#animation-timing-function):

> The `animation-timing-function` property describes <u>how the animation will progress</u> between each pair of keyframes

_"How the animation will progress"_ means how fast or how slow an animation will start and end.

The `animation-timing-function` accepts the following values:

* `ease` - This is the default value and the animation will start slow, then fast, then end slowly
* `linear` - The animation will start and end with the same speed
* `ease-in` - The specifies an animation with a  slow start
* `ease-out` - This is opposite of `ease-in` and it specifies an animation with a slow end
* `ease-in-out` - This combine the behavior of `ease-in` and `ease-in-out` therefore the animation will have  a slow start and end

```css
.box {
 /* All other properties remain the same */
 
 animation-timing-funtion: ease-in-out;
}
```

Note _the speed of the animation_ at the beginning and at the end.

###__`animation-fill-mode`__

From [the specification](https://www.w3.org/TR/css-animations-1/#animation-fill-mode):

> The `animation-fill-mode` property defines what values are applied by the animation outside the time it is executing.

This is quite tricky, so let's do some explanation.

By default CSS animations do not affect an element before the _first keyframe_ or after the _last keyframe_.

The _first keyframe_ means any code inside the `from` code block or _comma-separated percentage_ values and the _last keyframe_ means the code inside the `to` code block or _comma-separated percentage_ values.

Using `animation-fill-mode` we can override this behavior and the animation _can still be in effect after its execution time_.

The `animation-fill-mode` property accept the following values:

* `none` - This is the default value. Animation will not apply any styles to the element before or after it is executing
* `forwards` - The element will retain the style values that is set by the last keyframe
* `backwards` - The element will get the style values that is set by the first keyframe 
* `both` - The animation will follow the rules for both forwards and backwards, extending the animation properties in both directions

```css
.box {
 /* All other properties remain the same */
 
 animation-fill-mode: forwards;
}
```

Observe the result in the browser and take note of the execution time of `15s` (excluding animation delay) which means the animation has completed but with the `animation-fill-mode` in play the _box_ retains the last keyframe of the animation.

![A tomato colored box on a white background](https://thepracticaldev.s3.amazonaws.com/i/vt3s52kqkmf1cs0ofen0.PNG)

###__`animation-play-state`__

This specify whether the animation is running or paused.

It accepts the following value:

* `running`
* `paused`

```css
.box {
 /* All other properties remain the same */
 
 animation-play-state: paused;
}
```

Save and refresh your browser, you will realize the box will not move as _the animation is paused_.

You can click the _play button_ in the _Developer Tools_ to run the animation.

![A tomato colored box on a white background](https://thepracticaldev.s3.amazonaws.com/i/n6h9gxcue3wffjda4nuc.PNG)

###__`animation`__

This is the shorthand for `animation-name`, `animation-duration`, `animation-timing-function`, `animation-delay`, `animation-iteration-count`, `animation-direction` in that particular order.

Armed with this we can re-write our code as

```css
.box {
 /* All non-animation properties remain the same */

 /*
  * 1. animation-name
  * 2. animation-duration
  * 3. animation-timing-function
  * 4. animation-delay
  * 5. animation-iteration-count
  * 6. animation-direction
 */
            /*1*/ /*2*/ /*3*/       /*4*/ /*5*/  /*6*/
 animation: slide 3s    ease-in-out 3s    3      alternate;
```

You should know that all these properties are ignored in the _keyframe block_, with the exception of `animation-timing-function`.

```css
@keyframes slide {

  /*
   * All animation properties like animation-delay and
   * animation-duration are ignored in this block with
   * the exception of the animation-timing-function.
   *
  */

}
```

<hr>

##__CSS TRANSITIONS__

CSS Transitions are presentation effects and they allow property changes in CSS values to occur smoothly over a specified duration.

To create a transition effect, two requirement must be satisfied:

* A CSS property
* The duration of the effect

The following properties are used to create transitions:
* `transition-poperty`
* `transition-duration`
* `transition-timing-function`
* `transition-delay`
* `transition`

###__`transition-poperty`__
The `transition-property` specifies the name(s) of the CSS properties to which transitions should be applied.

_You should comment or delete the keyframes and all related animation properties from the box before proceeding._

Now update the `.box` with the following:

```css
.box {
  /*
    * All non-animation properties remain the same
    * with the exception of the background-color which
    * has been updated to #1560bd
    *
  */

  transition-property: height;
}
```

###__`transition-duration`__

The duration over which the transition should occur.

```css
.box {
  /* All other properties remain the same */

  transition-duration: 3s;
}
```

At this point we can see some transition effect based on human interaction. We'll check when the user _Mouse over_ the box and then increase its height.

```css
.box:hover {
  height: 200px;
}
```

The effect in the browser when the user _mouse over_ the box:

![A box on a white background](https://thepracticaldev.s3.amazonaws.com/i/ktf7sejo93i8pfh5g32o.PNG)

###­__`transition-timing-function`__

This is similar to `animation-timing-function` and it specifies the speed of the transition.

The`transition-timing-function` accepts the following value:

* `ease`
* `linear`
* `ease-in`
* `ease-out`
* `ease-in-out`
* `step-end`
* `step-start`
* the `steps()` function

These values have been explained earlier with the exception of `step-end`, `step-start` and the `steps()` function.

The best way to understand `step-*` family of values is to write to  some code.

Update your code with snippet below and don't forget to save.

```css
.box {
  /* All other properties remain the same */

  transition-timing-function: step-end;
}
```

Switch over to your browser and _Mouse over the box_, the height of the box will increase sharply at the end of the duration specified with the `transition-duration`.

Make sure you have the _Developer Tools_ opened and you've switched to the _Animation_ tab.

<!-- try and create a sandbox -->

The `step-start` is the opposite of `step-end` and the animation will occur instantaneously when you _Mouse over_ the box.

On the other hand the `steps()` function allow you to specify the _number of steps_ the animation should take.  It accepts two parameters:

* The number of steps e.g 2, 3
* A timing function value between `step-start` and `step-end` specified by eliminating the `step-` prefix.

Switch to your code editor and update your code:

```css
.box {
  /* All other properties remain the same */

  transition-timing-function: steps(2, start);
}
```

Observe the _steps_ in the _second panel_ of the _Developer Tools_. The _steps_ in the _third panel_ indicate the _step_ is applied at the beginning of the animation.

![A blue box on a white background](https://thepracticaldev.s3.amazonaws.com/i/03wzbkwjeuwlzhjcgt44.PNG)

If you update the value to `steps(2, end)` the step direction will be different.

![A blue box on a white background](https://thepracticaldev.s3.amazonaws.com/i/jvfdfvdwrv0tza59tu3r.PNG)

###__`transition-delay`__
The `transition-delay` property specifies a delay (in seconds) for the transition effect.

```css
.box {
  /* All other properties remain the same */

  transition-delay: 3s;
}
```

In the image below the _blue part_ in the _second panel_ indicate when the transition will start as a result of the `transition-delay` property.

![A blue box on a white background](https://thepracticaldev.s3.amazonaws.com/i/isp5qihqhf0e81bf9klt.PNG)

###__`transition`__

This is shorthand for setting `transition-property`,  `transition-duration`, `transition-timing-function`, `transition-delay` in that particular order.

```css
.box {
  /*
   * 1. transition-property
   * 2. transition-duration
   * 3. transition-timing-funtion
   * 4. transition-delay
  */
            /*1*/  /*2*/ /*3*/      /*4*/
  transition: height 3s    step-start 3s;
}
```

<hr>

We've come along way but i have left out the following as they seem _advanced_:

* `cubic-bezier()` - used in the timing function for both animations and transitions
* Transforms - When transforms are combined with transitions and animations, some cool effects can be created
* Applying transitions to more than one property
* Using `animation-timing-function` inside a keyframe.

If you are feeling adventurous you can read [Andreas Müller](https://dev.to/devmount) post on CSS animation by creating some loaders.

{% link https://dev.to/devmount/learn-css-animation-by-creating-pure-css-loaders-3lm6 %}

The next topic is more of theory than code and it's about _Naming Conventions in CSS_.