useAnimateOnScroll
Hook that applies enter and leave CSS animations to elements based on viewport intersection.
Usage#
import { useAnimateOnScroll } from '@primereact/headless/animateonscroll';const { rootProps } = useAnimateOnScroll({ enterClassName: 'fade-in' });
return <div {...rootProps}></div>;useAnimateOnScroll wires an Intersection Observer to a single element and toggles CSS animation classes based on viewport visibility. See Primitive for a component-based API.
Features#
- Viewport-driven animation — applies an enter class when the element scrolls in and a leave class when it scrolls out
- Intersection control — pass
root,rootMargin, andthresholdto tune when the observer fires - Single-shot mode —
oncedisconnects the observer after the first entry so the animation never repeats - Automatic class cleanup — animation classes are removed on
animationendandtransitionendto leave a clean DOM - Data-attribute hooks —
data-enteranddata-leaveflip on the root during each phase for CSS targeting
Working with callbacks#
Pair enter and leave classes#
Combine enterClassName with a matching leaveClassName when you need bidirectional motion tied to scroll position.
const { rootProps } = useAnimateOnScroll({
enterClassName: 'slide-in',
leaveClassName: 'fade-out'
});Fire the animation only once#
Set once when the element should animate in on first view and then stay in its final state even as the user scrolls past it.
const { rootProps } = useAnimateOnScroll({ enterClassName: 'fade-in', once: true });Tune the trigger point#
Use threshold and rootMargin to require more of the element to be visible before the animation starts, which is useful for larger hero sections.
const { rootProps } = useAnimateOnScroll({
enterClassName: 'fade-in',
threshold: 0.8,
rootMargin: '0px 0px -100px 0px'
});Scope intersection to a scroll container#
Pass an element as root to observe intersection inside a scrollable panel rather than the viewport.
const scrollRef = React.useRef<HTMLDivElement>(null);
const { rootProps } = useAnimateOnScroll({
enterClassName: 'fade-in',
root: scrollRef.current
});Styling with data attributes#
The root element carries data-scope="animateonscroll" and data-part="root". During each animation phase, data-enter or data-leave is set so you can target mid-animation state from CSS.
[data-scope='animateonscroll'][data-enter] {
will-change: opacity, transform;
}
[data-scope='animateonscroll'][data-leave] {
pointer-events: none;
}API#
useAnimateOnScroll#
| Name | Type | Default |
|---|---|---|
enterClassName | string | — |
| CSS class names that are applied when the element enters the viewport. | ||
leaveClassName | string | — |
| CSS class names that are applied when the element leaves the viewport. | ||
once | boolean | false |
| When enabled, animation is triggered only once. | ||
Accessibility#
No keyboard behavior — animations trigger based on viewport visibility only. See Primitive for full WAI-ARIA compliance details.