Let’s cut to the chase, guys. This is what you will get after reading this article:

The statistic numbers for each column will start from 0 and will be counted till the total number(stored on a data attribute on each column) with an animation applied to that counting. Standard used for the animation will be Javascript.
I will start with providing you the code first and then if you are also interested on explanation, then you can read further. Sounds like a fair deal, right?
So, let’s start with the HTML code:
<h2>Statistics</h2>
<div class="stats">
<div class="statsBox">
<span data-total="100">0</span>
<p>Visitors</p>
</div>
<div class="statsBox">
<span data-total="68">0</span>
<p>Likes</p>
</div>
<div class="statsBox">
<span data-total="36">0</span>
<p>Comments</p>
</div>
</div>
Now the most important part, the Javascript:
const animateNumber = (el, total, currentNumber) => {
currentNumber += 1;
el.innerHTML = currentNumber;
requestAnimationFrame(() => {
if(currentNumber !== +total) {
setTimeout(() =>{
animateNumber(el, total, currentNumber);
}, 10);
}
});
}
document.querySelectorAll('[data-total]').forEach(el => {
const total = el.dataset.total;
const currentNumber = 0;
animateNumber(el, total, currentNumber);
});
And finally the CSS code for the “design”, but you can do your design:
h2 {
text-align: center;
margin-bottom: 20px;
}
.stats {
display: flex;
justify-content: center;
gap: 5px;
font-size: 1.5rem;
text-align: center;
}
.statsBox {
background: #ccc;
padding: 10px;
flex: 0 1 65px;
}
.stats p {
font-size: .7rem;
}
Now if your visit was just for copy-paste purposes, then thank you for visiting and come again. If you are interested also on some explanations for the Javascript, then let’s continue.
The first step – finding the elements that need the animation

First of all we search for HTML elements that have the data-total attribute on it and after finding them we take that attributes value, that represents the final number on that element. The starting number could be something different then 0, that is your decision. If you always want 0 as a starting number just remove the constant and the currentNumber argument from the function and use 0 later on.
On each match for the HTML element we call one time the animateNumber function with 3 arguments:
- the element itself(el)
- the final number(total)
- currentNumber(starting number)
Second step – creating the function for incrementing the number in the counter by one

The animateNumber function increments the currentNumber variable by 1 and than it replaces the content of the element with the updated number.
Third step – Now we wait till the browser is ready and recall our function to increase our number with 1 and update it in the HTML

This function will actually use something called requestAnimationFrame method that calls a function right before the browser repaints the DOM. The animationFrame is executing 60 times per second the most. Using it will make sure that you never execute some animation between repaints.
We use a condition to check if the currentNumber has reached the desired final amount. If yes, then it will stop the recursion.

Fourth step – If the animationFrame(the 60 times per 1000 miliseconds timeframe) is too fast, we slow it down with setTimeout

That’s it. No conclusions whatsoever, just copy paste the code and enjoy the animation. Cheers!