CSS-animations

CSS animations allow doing simple animations without using JavaScript. In this case, JavaScript is used for controlling the animation and making it better with a little code.

CSS Transitions

Making CSS transitions is quite simple. You describe a property and the way its changes may be animated. Once the property is changed, the animation is painted by the browser.

So, all you need is to change the property.

Let’s consider an example where CSS is animating background-color changes:

.animated {
  transition-property: background-color;
  transition-duration: 5s;
}

In case an element has .animated class, any background-color is animated within 3 seconds.

In the example below, click the button to see the animated background:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #color {
        transition-property: background-color;
        transition-duration: 5s;
      }
    </style>
  </head>
  <body>
    <button id="color">Click on button</button>
    <script>
      color.onclick = function() {
        this.style.backgroundColor = 'green';
      };
    </script>
  </body>
</html>

Four properties describe CSS transitions. They are transition-property, transition-duration, transition-timing-function, and transition-delay.

The transition property allows declaring them together in the following sequence: property duration timing-function delay. It can also animate different properties at once.

For example, the button below is animating both the font-size and the color:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #growing {
        transition: font-size 5s, color 3s;
      }
    </style>
  </head>
  <body>
    <button id="growing">Click on button</button>
    <script>
      growing.onclick = function() {
        this.style.fontSize = '36px';
        this.style.color = 'green';
      };
    </script>
  </body>
</html>

Now let’s take an overview of the properties.

Transition Property

In the transition property, a list of properties is written to animate. For example, left, margin-left, height, color. However, not all properties can be animated.

Transition-duration

This property indicates the duration of the animation. In other words, in the transition-duration, you specify how long the animation should last. The time should be set in the CSS time format. It can be in seconds (s) or milliseconds (ms).

Transition-delay

In the transition-delay property, the delay before the animation is indicated. For example, if the transition-delay is 3s, then the animation starts 3 seconds after the change.

Here, negative values are also available. In this case, the animation will start from the middle. For example, if the transition-duration is 2s, the delay is -1s, then the animation will take 1 second starting from the half.

Let’s have a look at the case where the animation shifts numbers from 0 to 9 with the CSS translate property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #digitId {
        width: .6em;
        overflow: hidden;
        font: 36px monospace;
        cursor: pointer;
      }
      #stripe {
        display: inline-block
      }
      #stripe.animate {
        transform: translate(-90%);
        transition-property: transform;
        transition-duration: 6s;
        transition-timing-function: linear
      }
    </style>
  </head>
  <body>
    Click below to animate:
    <div id="digitId">
      <div id="stripe">123456789</div>
    </div>
    <script>
      stripe.onclick = function() {
        stripe.classList.add('animate');
      };
    </script>
  </body>
</html>

The transform property is animated as follows:

#stripe.animate {
  transform: translate(-90%);
  transition-property: transform;
  transition-duration: 6s;
}

In the example, demonstrated above JavaScript adds to the element the class .animate for the animation to start:

stripe.classList.add('animate');

Transition-timing function

The transition-timing function describes how the process of animation is distributed along the time. It is considered the most complicated property. This property accepts two types of values: a so-called Bezier curve or steps. We are going to start from the Bezier curve.

Bezier Curve

The timing function is set as a Bezier curve with four control points, satisfying the following conditions:

  1. The first control point: (0,0).
  2. The last control point: (1,1).
  3. The values x must be in the interval 0..1, for the intermediate points, and y can be anything.

The syntax of the Bezier curve in CSS is the following: cubic-bezier(x2, y2, x3, y3)

Generally, the timing process specifies how fast the process of the animation goes in time.

  • The time is the x axis: 0 – the moment of start, 1 – the last moment of the transition-duration.
  • The y axis indicates the completion of the process: 0 – the starting property value, 1 – the finishing value.

So, it is just a straight line. As the time (x) goes, the animation’s completion (y) passes from 0 to 1.

See how the image is going from left to right with the permanent speed in the following example:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      .imgClass {
        position: relative;
        cursor: pointer;
        width: 200px;
        height: 140px;
        left: 0;
        transition: left 6s cubic-bezier(0, 0, 1, 1);
      }
    </style>
  </head>
  <body>
    <img class="imgClass" src="https://www.w3docs.com/uploads/media/default/0001/05/9eb9e9cba721ba3bb5e653751449173197f2924a.png" onclick="this.style.left='450px'">
  </body>
</html>

The curve is the basis for the CSS transition. A Bezier curve can also make the animation get out of its range. Any coordinates can be set for the control points of the curve. They can be even negative or huge. The curve itself will vary low or high and make the animation get beyond its standard range.

The animation code will look like this:

.imgClass {
  left: 120px;
  transition: left 6s cubic-bezier(.3, -1, .3, 2);
  /* JavaScript sets left to 600px */
}

If you click the train you can see the following:

  • First of all, the train goes back: left is less than 120px.
  • Afterward, it goes forward, a bit farther than 600px.
  • Then it goes back again – to 600px.

Here is another example:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      .imgClass {
        position: relative;
        cursor: pointer;
        width: 200px;
        height: 140px;
        left: 120px;
        transition: left 5s cubic-bezier(.3, -1, .3, 2);
      }
    </style>
  </head>
  <body><img class="imgClass" src="https://www.w3docs.com/uploads/media/default/0001/05/9eb9e9cba721ba3bb5e653751449173197f2924a.png" onclick="this.style.left='600px'"></body>
</html>

Steps

It is possible to split the animation into steps with the help of the timing function steps (number of steps[, start/end]).

The example of a list of digits, without any animation, is shown below:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #digitId {
        border: 1px solid green;
        width: 1.5em;
      }
      #stripeId {
        display: inline-block;
        font: 36px monospace;
      }
    </style>
  </head>
  <body>
    <div id="digitId">
      <div id="stripeId">0123456789</div>
    </div>
  </body>
</html>

You can make the digits appear separately by changing the part of the list outside of the red window to invisible and shifting the list to the left with every step.

There can be nine steps. A step move for every digit looks like this:

#stripeId.animate {
  transform: translate(-90%);
  transition: transform 6s steps(9, start);
}

The action will look as follows:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #digitId {
        width: .6em;
        overflow: hidden;
        font: 36px monospace;
        cursor: pointer;
      }
      #stripeId {
        display: inline-block
      }
      #stripeId.animate {
        transform: translate(-90%);
        transition-property: transform;
        transition-duration: 6s;
        transition-timing-function: steps(9, start);
      }
    </style>
  </head>
  <body>
    Click:
    <div id="digitId">
      <div id="stripeId">0123456789</div>
    </div>
    <script>
      digitId.onclick = function() {
        stripeId.classList.add('animate');
      }
    </script>
  </body>
</html>

Event Transitionend

After the completion of the CSS animation, the transitionend event occurs. It is mainly used for acting after the animation is over. For example, here the ship starts swimming there and back on the click. The animation starts with the go function and re-runs every time the transition finishes and flips the direction, as follows:

img.onclick = function () {
  let times = 1;
  function animate() {
    if (times % 2) {
      // swim to the right
      img.classList.remove('back');
      img.style.marginLeft = 100 * times + 150 + 'px';
    } else {
      // swim to the left
      img.classList.add('back');
      img.style.marginLeft = 100 * times - 150 + 'px';
    }
  }
  animate();
  img.addEventListener('transitionend', function () {
    times++;
    animate();
  });
};

There are some unique properties in the event object for transition end. One of them is the event.propertyName: the property that has finished the animation. It is better when multiple properties are animated simultaneously. The second one is event.elapsedTime: the time that the animation took (in seconds). It doesn’t include transition-delay.

Summary

With the help of the CSS animation, you can smoothly animate changes of one or multiple CSS properties. They are mainly used for making simple animations and are handy for most animation tasks. But for most complex tasks, you can use JavaScript animations that are covered in the next chapter.




Do you find this helpful?

Related articles