Web Components On Fire
Numbers that grow in front of your eyes are oddly satisfying and even though they’ve become something of a landing page trope, they’re still kinda fun. Surely, you know what I’m talking about, but here’s a demo anyway.
The <hotfx-counter>
custom element makes these transitions very easy. To add a counter, first add
this script to your page:
Then you can just wrap your number in the custom element, like so:
<hotfx-counter>42</hotfx-counter>
Note that this is just the number, not any other characters or words like % or trillion. That’s actually all you need to get this working, but let’s see what you can customize.
By default the number will take 1 second to reach the correct value. If you want a longer or a shorter transition you
can set the speed using the duration attribute, which accepts a value in milliseconds (so duration=1000
for
1 second).
If you’ve got a number that’s always changing, you can just update the value in the DOM and the transition will just magically happen.
This animation will wait for the reader to scroll onto the number before it runs. If you want to run the animation
again, you can use the run()
method on the element. Just call it in JavaScript like
document.querySelector('hotfx-counter').run()
.
That’s exactly how we built the demo at the top of the page, which animates again when you hit the “Do it again” button.
There is a way to build these counters with only CSS. This involves setting a custom property to a number, using that on a pseudo element and transitioning the property, as described on CSS Tricks.
In general, I’m a big fan of using CSS as much as possible and JavaScript as little as possible, but in this case, I think the custom element may be a better choice.
For one thing, the number lives in your HTML as opposed to your styles, which is good new for search engines and other crawlers. Also, the code is cleaner and it’s easier to render or update using a front-end library like React.
What is missing from this counter? If you find any bugs or have feature requests, please open an issue on the repo.