A progress bar that follows the scroll position of the page or of a container.
Installation
Usage
<script setup lang="ts">
import {
ScrollProgress,
ScrollProgressContainer,
ScrollProgressProvider,
} from '@animate-ui/vue/primitives/scroll-progress';
</script>
<template>
<!-- A scrollable container. -->
<ScrollProgressProvider>
<ScrollProgress class="h-1 bg-foreground" />
<ScrollProgressContainer class="h-96 overflow-y-auto">
…
</ScrollProgressContainer>
</ScrollProgressProvider>
<!-- The whole page. -->
<ScrollProgressProvider global>
<ScrollProgress class="fixed inset-x-0 top-0 h-1 bg-foreground" />
</ScrollProgressProvider>
</template>Animation
- The bar follows the scroll position on a spring without overshoot (stiffness 250, damping 40), so it glides instead of jumping on wheel steps.
- By default it grows in width (
mode="width", from 0 to 100%), so rounded ends keep their shape;heightdoes the same vertically.scaleXandscaleYscale it with a transform instead, from itstransform-origin(the center unless you set one, e.g.origin-left). - Scrolling never re-renders Vue: the bar is driven by motion values.
- Under reduced motion, the bar tracks the scroll position without easing.
API Reference
ScrollProgressProvider
| Prop | Type | Default |
|---|---|---|
global? | boolean | false |
direction? | 'vertical' | 'horizontal' | 'vertical' |
transition? | SpringOptions | { stiffness: 250, damping: 40, bounce: 0 } |
#default | slot | - |
ScrollProgress
| Prop | Type | Default |
|---|---|---|
as-child? | boolean | false |
mode? | 'width' | 'height' | 'scaleX' | 'scaleY' | 'width' |
...props? | HTMLMotionProps<'div'> | - |
ScrollProgressContainer
The scrollable element (without global). Make it scroll with overflow-y-auto.
| Prop | Type | Default |
|---|---|---|
as-child? | boolean | false |
...props? | HTMLMotionProps<'div'> | - |
useScrollProgress
Returns getters for the progress (raw, 0 to 1) and scale (smoothed) motion values, direction and global, with the container ref.