The CSS animation-delay property is obviously used to delay the commencement of a CSS animation for a specified amount of time. But, like many CSS properties, there’s more than meets the eye… Using animation-delay you can create a variety of complex and beautiful pure CSS animations with ease, by applying it to a set of otherwise identical elements at varying time values.
All of the following examples follow the same basic setup: a number of looping animated elements are created, all of which are identical save for a unique numeric class which allows each element to be selected individually via CSS. Using this, a different animation-delay time can applied to each element, causing each animation to run asynchronously with the others to create various effects. I’ll go into more detail in the examples, below.
Basic Example: Loading Dots
This example demonstrates how to use this technique to make a simple CSS loading animation. The steps to create this are as follows:
- Create a number of elements all of the same class, in this case “loadingDot”. Position them however you like.
- Create a CSS keyframe animation, and assign it to the .loadingDot class. Animate this however you like- in this instance I’m animating transform: scale.
- Add a unique class to each element: in this case, I’ve assigned .loadingDot‑‑1, .loadingDot‑‑2 etc. (Remember that a class name cannot start with a number).
- Finally, add the animation-delay property to each unique class, with a different delay time for each one. Ensure that the delay times are incrementing with a set interval for a cleaner looking animation (eg .10s, .20s, .30s etc), although you can choose whichever interval you like.
We can use the same technique to make more complex animations- find more examples below. Note, going forwards I will be using Sass and Haml to automate creating some of the HTML & CSS. Don’t worry if you’re unfamiliar with either of these- you can view the compiled HTML & CSS in all the following examples, which shows how it would look had it been written by hand.
Negative animation-delays: Falling Rain
This next example uses negative animation-delay values, which has a subtly different effect to using a positive value. Using a negative animation-delay value makes an animation commence at that point during its keyframe sequence. This is essential for something like the falling rain effect above, which wouldn’t work if we had to wait for some of the elements to start animating.
The steps to create this are as follows:
- Set html and body to 100% height.
- Create a number of elements all of the same class, in this case “raindrop”. The .raindrop class should use position: absolute, with top and left set to 0. Aside from that they can be styled however you like, although don’t make them too big.
- Add a unique class to each element: in this case, .raindrop‑‑1, .raindrop‑‑2, etc). In this example I’ve used HAML to automate the above two steps, to avoid writing out large amounts of HTML manually.
- Create a CSS keyframe animation, animating transform: translate to make an element fall from the top of the screen to the bottom.
- Assign the keyframe animation to the .raindrop class. Ensure that a linear timing function is being used, and that the animation is set to loop infinitely.
- Create the unique CSS class selectors (.raindrop‑‑1, etc) and add a random negative animation-delay to each one. The value doesn’t matter so much, so long as the random values are evenly spread and are lower than or equal to the animation’s duration.
- Add a random position: left value to each unique raindrop class, in order to space the raindrops along the X-axis. Each value should be between 0% and 100%. Note, I’ve used Sass to automate the above two steps, to avoid writing out large amounts of CSS manually.
You should now be seeing a shower of raindrops falling down on your screen. This effect perhaps looks a little boring in its raw state, but with a few changes you can make more interesting effects such as a starfield or falling snow.
If you’re still confused about how negative animation-delay affects things, try flipping the animation-delay values from negative to positive and notice how the animation changes.
Fixed animation-delay Intervals: 8Bit 3D Road
This final example increments animation-delay values on a fixed interval in order to create a perfectly looping animation. The interval is calculated via (number of elements / animation duration), then each animation-delay value is set to ( interval * element number ).
Don’t worry if this sounds confusing. The following steps outline the process of constructing this animation, although we’ll be moving more quickly than before:
- Set the body to be a 3D projection, so we can transform child elements on the Z-axis (to simulate 3D movement into the screen).
- As previously, create a number of elements of the same class, each with an additional unique class (in this case, “roadStrip” and “roadStrip‑‑1”, etc). The roadStrip class should be positioned at the bottom of the viewport, but otherwise style it however you like.
- Create a keyframe animation which animates a transform along the Z-axis. In this example I’m also animating opacity, to fade the roadStrips in and out at the beginning and end of the animation, although this isn’t essential. Assign this to the roadStrip class.
- Work out your interval value by calculating animation duration / total quantity of roadStrips.
- Apply animation-delay to each unique roadStrip class. Each animation-delay value should be calculated as interval * roadStrip ID number.
By now you should have a 3D road, moving into or out of the screen. Again, if you think the effect’s a little plain then it can be made much more exciting with just a few tweaks.
I hope you’ve enjoyed this tutorial, and learned that it’s pretty easy to create a huge amount of different animations using this technique. Drop me a line if you have any questions, and have a look through my Codepen for some more examples.