Skip to content
EspañolEnglish
All components (204)

Reading progress bar

Surfaces · ReadingProgress

What it is and when to use it

The thin strip stuck to the top (or bottom) of the window that says how much of a long page you have read. It measures itself as you scroll.

When to use it

  • Articles, guides, legal terms: long pages that are read from top to bottom.
  • One per page, mounted once: it listens to the scrolling of the whole window, not of a container.

When not to

  • A task that advances and finishes (upload, import): Progress.
  • A level that goes up or down (used space, stock): Gauge.
  • A page that fits entirely in the window: there is nothing to scroll through and the strip appears full.

Keyboard: it cannot be focused or pressed (pointer-events: none).

Accessibility: by default it is decoration and is declared as such (aria-hidden): nobody can stand a percentage that changes with every turn of the wheel, read aloud, and what has been read is already known from reading it. withLabel turns it into a progressbar named "Reading progress", with the rounded value ("62% read"); that name cannot be changed. The measurement runs inside a requestAnimationFrame, so layout is not recalculated on every scroll event.

Fine-tuning: no variables of its own: it is adjusted with the classes amset-reading, amset-reading--top/--bottom (depending on position) and amset-reading--<tone> (accent by default). It is position: fixed, in the --amset-layer-reading layer; the height is set by thickness (3 px by default).

On this page: each story sits in its own frame. Scroll inside it to see the strip advance.

What it looks like

Scroll this page: the ribbon at the top of this box advances with how much you have read. On a real page it sticks to the edge of the window.

<ReadingProgress tone="accent" thickness={4} />
<article>...</article>

Props

Import it with import { ReadingProgress } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
classNamestringMerged with the library classes; it does not replace them.
position"top" | "bottom"Stuck to the very top or bottom. Top by default.
thicknessnumberHeight of the ribbon. 3 px by default.
tone"neutral" | "accent" | "secondary" | "tertiary" | "info" | "success" | "warning" | "error"The color of what has been read. `neutral` is the gray of the secondary ink. `accent` by default.
withLabelbooleanThe count also with numbers and for the screen reader. By default no: a reading ribbon is decoration, and announcing the percentage on every scroll is unbearable.

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: