All hooks / Viewport and media
useScrollProgress
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.
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
| Uses | Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS |
|---|---|---|---|---|---|---|
| ResizeObserverWidely available | 64+ | 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.