← All effects

Count-in Sections

ScrollVanilla JS · zero dependenciesIntersectionObserver fires the start gun
Scroll down — the numbers wait for their entrance…
…and scroll back up to reset them (replay is a setting).
scroll inside ↓
-- fps
prefers-reduced-motion detected — numbers appear at their final values

X-ray · layers

off = counts immediately
one counter after another
sprint early, land gently

Parameters

Count time1400 ms
Stagger gap180 ms
Trigger point0.40
Replay1 = every visit
your version · updates as you tinker

How this effect works

The counting is the easy half — it's the Percentage Counter's easing on arbitrary targets. The craft is in when it starts. An IntersectionObserver watches the stat row and fires the moment enough of it (the trigger point) enters the viewport — no scroll listener, no per-frame position checks; the browser does the watching natively and wakes us exactly once.

That timing matters because a counter that already finished before you saw it is a plain number — the entire effect is the entrance. Stagger starts the counters left to right like a relay instead of a chorus, and replay decides the second visit: reset when it leaves the viewport (a little show every time) or count once and stay counted (calmer, better for long pages).

Production notes: prefers-reduced-motion: final values render immediately · IntersectionObserver is free — never poll getBoundingClientRect on scroll for this · format big numbers (12,500 not 12500); the eye reads the shape · the copied snippet is self-contained with its own demo scroll box.