Skip to the content

Rolling stats

A row of key figures that roll as they come into view.

Become a member to unlock the full effect today.

Join now

Already a member? Sign in

Documentation

  1. Copy to Webflow

    Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: Webflow removes any font your site has not installed.

  2. Add custom CSS

    Before the script runs, a marked number is hidden with visibility and keeps its room, so the written number never flashes before the drums. It shows by itself after four seconds if the script never comes, and at once without JavaScript, through the noscript line the paste carries inside its Embed. The size, weight and tracking of a number are the page's own; the stylesheet only asks for tabular figures, so nothing moves sideways.
  3. Add custom JS

  4. Use it on your own elements

    Custom attributes
    Select the element on the canvas and open the Settings panel. Under Custom attributes, add a pair: the name on the left, the value on the right.
    Custom attributeWhat it does
    data-rolling-stats Marks the block that holds the figures: a row, a grid, a whole section. It takes no value: leave the value field empty. Every number marked data-rolling-stats-value inside it rolls as it comes into view. A single number takes both attributes on the same element.
    data-rolling-stats-value On each number. Left empty, the number is read from the text as it is written: every digit becomes a drum, the commas, spaces and points between digits stay in place, and what comes before the first digit or after the last one comes in once the number has landed. Given a bare number, data-rolling-stats-value="124800", that number is shown instead, its thousands joined by the separator setting. Without it on any element of the block, nothing rolls and the console says so. [ Required ]
    data-rolling-stats-rule On an empty box near a number, in the same item: the rule of that figure. Its own height and colour are the track, and the script lays the fill over it. Without it, the script adds a hairline under the number. [ Optional ]
    data-rolling-stats-prefix On a number: the words shown before it, data-rolling-stats-prefix="$", in place of what the text holds before its first digit. data-rolling-stats-suffix does the same for the words after it. Meant for a number given in data-rolling-stats-value. [ Optional ]
    data-rolling-stats-state Written by the engine on the block: ready while figures wait, playing, done once all have played, static under reduced motion. Each number carries data-rolling-stats-stat the same way. Never written by hand. [ Optional ]
    Settings
    Every setting is a custom attribute too, added the same way and on the same element. An attribute always wins over the defaults written in the code.
    AttributeDefaultWhat it is
    data-rolling-stats-color #ffab1a Colour of the rule while it fills, and of the flash a digit carries as its drum lands; once the number has landed the rule takes the ink of the text. Options: any CSS colour, the amber #ffab1a by default.
    data-rolling-stats-ink inherit Colour of the digits and of the words around them. Options: inherit (the colour of the text, the default), or any CSS colour.
    data-rolling-stats-duration 1.6 Time one figure takes, in seconds, from the first move to its last drum at rest. The drums to the left land earlier, 0.11 s apart.
    data-rolling-stats-stagger 0.12 Delay, in seconds, between two figures that come into view together, in the order of the markup.
    data-rolling-stats-overshoot 0.5 How far a drum runs past its digit before it is taken back, in digits, 0 to 2.
    data-rolling-stats-separator , Mark put between the thousands of a number given in data-rolling-stats-value. A number read from the text keeps the marks it was written with, and this is not used. A point here turns the decimal mark into a comma. Options: , by default, a point, a space, an apostrophe, or nothing for no grouping.
    data-rolling-stats-once true Whether a figure plays one time only. Options: true (played once, then nothing watches the page any more), false (back on its start digits once it has fully left the window, and played again as it returns).
    data-rolling-stats-start-from zero The digits the drums wait on before they roll. Options: zero (every drum on 0), random (each drum on a digit of its own, the same on every load).

What it does

Rolling stats is a scroll animation for Webflow and vanilla JavaScript, with no library. Also called rolling number counter, odometer counter animation or number ticker animation.

A row of key figures that roll as they come into view. Every digit sits on a drum of its own. All the drums of a figure leave at the same moment, fast, and slow down to a crawl in which the last digits tick past at a pace the eye reads; the left drum lands first and the right one last, and each one runs half a digit past its mark and is taken back, the click of a mechanical counter. A landed digit flashes in the colour and takes the ink. The figures are tabular and the commas, spaces and points between digits never move, so nothing shifts sideways. Under each figure a rule fills while it rolls, and the words around the number, $, %, +, M, come in only once it has landed. Figures of one row leave one after the other. The number is read from the text as it is written, so there is nothing to format: any grouping, any language. Off screen nothing runs, and once played the component sleeps. One clock, no library. Under reduced motion the numbers stand as written with the rule full. Pattern type count up, odometer, number ticker.

Updated

Questions

Add the custom attribute data-rolling-stats to the block that holds the figures and data-rolling-stats-value to each number, both with an empty value. In the Designer a marked number shows as written and stays editable; the drums only exist in the preview and on the published page.

No. Each digit sits on a drum of its own and one requestAnimationFrame clock turns them all, with no library and no build step. Off screen nothing runs, and once a block has played nothing watches the page any more.

Write the number in the text the way it should read, 124,800+, 98.6% or $4.2M: every digit becomes a drum, the marks between digits stay where they are, and what sits before or after the number comes in once it has landed. For a CMS field that holds a bare number, write data-rolling-stats-value="124800"; its thousands are then joined by data-rolling-stats-separator, a comma by default.

Raise data-rolling-stats-duration, the time in seconds one figure takes from its first move to its last drum at rest, 1.6 by default. Lower is a quick tick that is barely read, and past 2.5 the last digits crawl. data-rolling-stats-stagger, 0.12 by default, is the delay between two figures that come into view together.

No, by default a figure plays one time. With data-rolling-stats-once="false" it goes back to its start digits once it has fully left the window and plays again as it returns. A figure starts once 60% of it is inside the window.