019

Count-Up Stats

£10 or the whole Vault, £99

Entry- or scroll-triggered number counters with locale-aware formatting, staggered reveals, synchronized progress visuals, and optional replay.

ScrollTrigger beginner
3 more details
scroll-revealcount-upstagger

This demo reads better at your own screen size than in the frame below:

Updated

About this effect

A stat counter effect that animates numbers from zero to their target on entry or as they scroll into view. Built on GSAP and ScrollTrigger, it preserves locale-aware thousands separators, currency prefixes, percentage suffixes, decimal precision, and one-time scroll behavior through simple data attributes. The JavaScript reads no class names, so the attributes go straight onto whatever stats markup you already have; the demo is an ordinary lead-figure-plus-supporting-metrics band. Optional fills, SVG rings, and a semantic replay control share the same staggered timeline.

Count-Up Stats - GSAP animation effect preview

What's included

9 items
  • Scroll-triggered counting that fires once per stat, never replaying mid-read
  • Locale-aware thousands separators via toLocaleString, with custom or disabled separators per counter
  • Prefix and suffix support for currency symbols, percentages, and plus signs
  • Decimal precision control with GSAP snap so values never show float noise
  • Staggered group reveals from a single data-count-stagger attribute on any container
  • Card reveals, progress fills, and pathLength-based SVG rings synchronized to each counter
  • Optional load trigger and semantic replay control for immediate dashboard sequences
  • Custom countup:start and countup:complete events for analytics or chained animations
  • Accessible: prefers-reduced-motion users see exact final values immediately, no counting

Perfect for

5 use cases
  • SaaS landing page metrics sections with staggered stat cards
  • Agency about pages showing projects delivered and client satisfaction
  • Annual report or investor pages with revenue and growth figures
  • E-commerce social proof strips with download and review counts
  • Nonprofit impact dashboards counting donations and people helped

How it works

2 sections

Each element with data-count-to climbs to its target in steps derived from its own decimal precision, so the number on screen is always one you would actually display. Values are formatted as they climb with Intl-backed toLocaleString (or a custom separator) plus any prefix and suffix, while optional fill and SVG ring hooks animate on the same timeline.

A group can start immediately with data-count-trigger="load" or retain the default once-only ScrollTrigger behavior. Reduced-motion visitors get exact static values, and the synchronous has-js gate falls back to the final HTML when JavaScript or the GSAP CDN is unavailable.

Plugins ScrollTrigger
Difficulty Beginner
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid effect

Purchase to unlock the code.

Buying Count-Up Stats opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£10 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

1. Add to your HTML <head>:

Code snippet omitted: it ships with the download.

The synchronous class prevents a first-paint flash. If GSAP is unavailable, script.js removes it so final HTML values remain visible.

2. Add before closing </body> tag:

Code snippet omitted: it ships with the download.

3. Add data attributes to any number element:

Code snippet omitted: it ships with the download.

Put the final value in the HTML as the element's text. It is the no-JavaScript fallback and what search engines index; the script replaces it with the animated count.

Options

Set these on each counter element:

Attribute Values Default Description
data-count-to Any number 0 Target value to count to (required)
data-count-duration Seconds 2 How long the count takes
data-count-decimals 0, 1, 2... 0 Decimal places shown while counting
data-count-prefix Any string none Text before the number, e.g. £, $
data-count-suffix Any string none Text after the number, e.g. %, +, M
data-count-separator Any string, or none Locale default Thousands separator. Omit for locale-aware grouping, use none to disable

Set these on wrapper elements:

Attribute Where Description
data-count-stagger A container of counters Groups every counter inside under one scroll trigger, offsetting each by this many seconds (e.g. 0.15). Attribute with no value uses the 0.15 default
data-count-block An ancestor of a counter Marks the block that reveals alongside the count (a whole stat card, not just the number). Without it, only the counter element itself animates
data-count-trigger="load" A stagger container Starts its timeline on page entry instead of using ScrollTrigger. Omit it to retain the default scroll trigger
data-count-primary A count block Marks the lead stat: it rises from a shorter distance and gets a small scale pulse as it lands
data-count-replay="#id" A semantic button Restarts the load-triggered timeline whose stagger container matches the selector
data-count-replay-message The same button Text announced in the live region on replay. Defaults to Values counted again.
data-count-fill An element inside a count block Scales an accent or progress fill from left to right with that counter
data-count-ring="73" An SVG stroke inside a count block Draws a pathLength="100" stroke to the supplied percentage with that counter

Using It With Your Own Design

The JavaScript is class-agnostic: every behaviour above is driven by data attributes, and nothing in script.js reads a class name from your markup. Drop the attributes onto whatever stat markup you already have and the effect works as-is.

Two things the stylesheet owns, and you will want to keep when you replace it:

  • The pre-hide gate. .has-js [data-count-block] { opacity: 0; transform: translateY(22px) } is what stops the stats painting at full opacity and then snapping back for the reveal. It is scoped to .has-js so the stats stay visible without JavaScript, and it is undone under prefers-reduced-motion.
  • The fill start state. [data-count-fill] bars start at scaleX(0) with a left transform origin; the reduced-motion block forces them to scaleX(1).

The demo's own layout classes (.stats, .stat, .stat--lead, .ring) are plain CSS with no behaviour attached, so rename or delete them freely.

Accessibility

  • Reduced motion: respects prefers-reduced-motion; counters skip the animation entirely and display their exact formatted final values immediately, and stat blocks appear without the fade/rise
  • Exact final values: onComplete writes the precise formatted target to the DOM, so assistive tech and users always end on the true number, never a mid-tween value
  • No-JS and blocked-CDN fallback: final values live in the HTML, while the has-js gate is absent without JavaScript and removed if GSAP cannot load
  • Replay semantics: the included control is a native button and announces replay status through a polite live region
  • Fires once by default: scroll-triggered groups retain once: true; replay is opt-in for entry-triggered presentations

Browser Support

Modern browsers (ES6+). Not compatible with IE11.

Dependencies

  • GSAP 3.12+
  • ScrollTrigger plugin

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.