Back to Feed
article 3m read

One version of my count-up tiles shows zero to anyone who turns motion off

Two versions of a count-up animation on my admin dashboard differ in one spot: the first prints a placeholder zero that never gets replaced when reduced motion is on, the second prints the real total and only lets the script write a zero right before it counts back up.

Article DepthPractice

Flow

The second version's two paths

  1. 1Page arrives with the real total

    The server's number is already on the tile.

  2. 2Read the target

    A missing target falls back to zero, where a dash would be more honest.

  3. 3Reduced motion on

    Write the target and stop.

  4. 4Motion allowed

    Swap in a zero, then count up a slice of the gap each frame until it lands.

One version of the count-up animation on my scheduling app's admin dashboard shows zero companies, zero users and zero log entries to anyone who has reduced motion turned on. Showing those three numbers is part of that screen's job, and this version shows a zero for each.

I found it by reading two diffs next to each other, not by seeing it in a browser.

Where the zero comes from

The tiles used to be plain. The server works out each total and prints it into the page. Then the dashboard got fade-in cards and numbers that tick up from zero. There are two versions of the tick-up change, both built on the same starting point.

The first version prints a zero on each tile and hides the real total in an attribute. A script counts the zero up to the real total. But if the person has asked for less motion, the script skips the counting, and nothing else ever puts the real number on the tile. The zero stays.

Putting the real total back first

The second version prints the real total on the tile again. The script then picks one of two paths, and both end with the right number:

tiles.forEach((el) => {
  const goal = Number(el.dataset.target);
  calm ? show(el, goal) : countUp(el, goal);  // only countUp writes a "0"
});

So the script only writes a zero on the path that starts counting right away. If the script skips or never loads, the server's number is still in the page. If it breaks after writing the zero, the zero stays.

The small parts that still go wrong

If you build one of these, these are the parts I'd look at hardest:

  • A missing total shown as zero looks like "empty". A dash is more honest.
  • The count starts on page load, not when the tile scrolls into view, so lower tiles may finish before anyone sees them.
  • A tab opened in the background can pause the count partway until you switch to it.

The fade-in under both versions

The cards start invisible in the stylesheet, and a script fades them in. With scripts off and motion on, the tiles likely never show up at all, under either version.

The check I'd add opens the page with motion off and compares each tile to the server's count.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward