The ScrollProgress component fills a thin bar as the reader moves through a page or a panel, scaling a single transform rather than resizing an element so it costs nothing on the scroll frame.
Add it with the CLI, open it in v0, or copy the source into your project.
Adds the component and installs its dependencies for you.
npx shadcn@latest add https://uibeats.com/r/scroll-progress.jsonEverything Scroll Progress accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
| container | RefObject<HTMLElement | null> | No default | Scroll container to track. Omit to track the window, which also switches the bar from absolute to fixed positioning |
| height | number | 3 | Thickness of the bar, in pixels |
| color | string | var(--primary) | Any CSS colour or gradient |
| position | 'top' | 'bottom' | top | Which edge of the container the bar sits on |
| smooth | boolean | true | Ease the bar toward the true position with a spring instead of tracking raw scroll deltas |
| className | string | '' | Additional CSS classes for styling |
Motion is a language, and most interfaces speak it badly.
A transition that runs too long reads as lag. One that skips a frame reads as a bug.
The fix is to move only what actually changed, and to move it the shortest distance that still explains itself.
Everything else holds still, so the one thing that moved is the thing you notice.