Scrolling up · bottom of page in view: no

All hooks / Viewport and media

useScrollProgress

288 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

How far the user has scrolled through an element, from 0 (its top at the top of the viewport) to 1 (its bottom at the bottom of the viewport). Returns a callback ref for the element.

Updates on page scroll, window resize, and when the element's own size changes (images loading, content added). An element shorter than the viewport counts as read once it is fully visible. 0 on the server and until the element is measured.

Import

import { useScrollProgress } from '@vincent.ri/react-tils'
// or only this hook
import { useScrollProgress } from '@vincent.ri/react-tils/useScrollProgress'

Usage

const [ref, progress] = useScrollProgress<HTMLElement>()
return (
  <>
    <div className="progress-bar" style={{ transform: `scaleX(${progress})` }} />
    <article ref={ref}>…</article>
  </>
)

Live demo

Scroll the page: the bar in the status bar fills up.

read: 0%

When to use it

A reading-progress bar for an article or docs page, or showing how much of a long form or terms text is left. For the whole page, put the ref on the element that wraps its content (<main>).

When not to

The content scrolls inside a container, not the page; use useElementScroll. For purely visual effects, CSS scroll-driven animations avoid re-renders where supported.

API

function useScrollProgress<T extends Element = HTMLElement>(): [(element: T | null) => void, number]

Returns [ref, progress], with progress from 0 to 1.

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
ResizeObserverWidely available64+79+69+13.1+64+13.4+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useReadingProgress, useScrollPercentage.