Animated Countdown
No extra elements needed

Thu Jul 29 2021
An animated countdown where each digit animates by moving from top to bottom, without using extra elements for each digit - only the :before pseudo-element.
I needed to create a simple countdown to a given time but I thought I would spice it up a little bit with some animation. I've always liked where the next digit seems to fall from the top and pushes the current digit down. There are plenty of examples of this online, but a lot of them seem to use extra elements for each digit, or at least one extra.
Which had me thinking, "Why not use the :before pseudo-element as the 'next digit', animate the element moving down, and then replace the element with the next digit?" And that's exactly what I managed to do!
Moving the Digit
The basic idea behind this idea is the following CSS:
span {
position: relative;
}
span:before {
content: attr(data-nextvalue);
position: absolute;
top: -80px;
z-index: -1;
}
span.moving {
transition: transform 500ms ease;
transform: translateY(80px);
}
Imagine the span
element is a digit. We set it's positioning to relative
and we set it's :before pseudo-element's content to the next digit (shown later). The :before element's positioning is set to absolute
and it's moved above the span element with top
.
Now when we want to move the digit downwards, we simply apply the .moving
class to it which will translate the element down by 80px
over 500ms using a combination of transition and transform
.
Setting the Digit's Next Value
To set the digit's next value, we use a data attribute. We can set this in javascript with the following:
digit.dataset.nextvalue = nextValue;
This is then set using the content
rule in the CSS above.
Replacing the Digit
Once the transform has finished, we need to set the digit to it's next value. We do this by removing the moving
class and setting the digit's innerHTML
to the next value after 500ms.
setTimeout(() => {
digit.classList.remove("moving");
digit.innerHTML = nextValue;
}, 500);
Wrapping Up
You can see the full code example on my CodePen: https://codepen.io/djdmorrison/pen/yLbKqvm