Version: 1.0 | Release Date: 20 April, 2026
Each counter uses custom attributes (no class needed):
<span counter-animation data-count="500" data-decimals="0" data-suffix="+">0</span>
data-count → final numberdata-decimals → decimal placesdata-suffix → text after numberdata-duration → animation speed<span counter-animation
data-count="99.9"
data-decimals="1"
data-suffix="%"
data-duration="3">0</span>
👉 Output: 99.9%
const duration = parseFloat(counter.dataset.duration) || 2;
👉 Change in HTML:
data-duration="1" <!-- fast -->
data-duration="3" <!-- slow -->
start: "top 80%",
👉 Options:
"top 90%" → starts earlier"top 70%" → starts later"top 50%" → middle of screenonce: true
true → runs once ✅false → repeats on scrollconst lenis = new Lenis();
const lenis = new Lenis({
duration: 1.0, // scroll speed
smoothWheel: true,
smoothTouch: false
});
counter-animation
data-count="300"
data-decimals="0"
data-suffix="+"
data-duration="2"
counter-animation attributedata-countAdjust:
start: "top 80%"
data-countdata-countdata-decimalsdata-suffixdata-duration