Animate on Scroll React component
A wrapper that brings content in as it scrolls into view: fade from any side, zoom, blur, flip or a clip-path wipe, one block at once or each child in turn, once or every time, watching the window or any scroll box.
When to use the Animate on Scroll component
Use Animate on Scroll on landing pages and long-form stories to bring sections, images and card grids in as people reach them, so the page feels alive without moving everything at once.
Keep effects consistent within a page (one or two), keep distances small, and leave body text of long articles static.
Installation
Add the Animate on Scroll component to your project with the shadcn CLI. It lands in components/animate-on-scroll.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add https://reactframe.com/r/animate-on-scroll.jsonOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeProps
<AnimateOnScroll /> accepts 11 props, all optional.
| Prop | Type | Default |
|---|---|---|
| children | React.ReactNode | — |
| effect | "fade-up" | "fade-down" | "fade-left" | "fade-right" | "zoom-in" | "blur-in" | "flip-up" | "clip-up" | "fade-up" |
| stagger Animate each direct child in turn, this many seconds apart (0 = animate as one block). | number | 0 |
| delay | number | 0 |
| duration | number | 0.7 |
| distance Distance (px) for the slide effects. | number | 32 |
| once Play only the first time it comes into view. | boolean | true |
| amount How much must be visible to start (0–1). | number | 0.25 |
| root A scroll box to watch instead of the window. | React.RefObject<Element | null> | — |
| as | "div" | "section" | "ul" | "ol" | "div" |
| className | string | — |
- childrenReact.ReactNode
- effect"fade-up" | "fade-down" | "fade-left" | "fade-right" | "zoom-in" | "blur-in" | "flip-up" | "clip-up"Default: "fade-up"
- stagger
Animate each direct child in turn, this many seconds apart (0 = animate as one block).
numberDefault: 0 - delaynumberDefault: 0
- durationnumberDefault: 0.7
- distance
Distance (px) for the slide effects.
numberDefault: 32 - once
Play only the first time it comes into view.
booleanDefault: true - amount
How much must be visible to start (0–1).
numberDefault: 0.25 - root
A scroll box to watch instead of the window.
React.RefObject<Element | null> - as"div" | "section" | "ul" | "ol"Default: "div"
- classNamestring
FAQ
- Does it replay when scrolling back up?
- Only if you set once={false}; then it reverses when it leaves the screen and plays again when it returns. By default it plays once.
- How do I animate items one by one?
- Set stagger to the gap in seconds. Each direct child is wrapped and animated in turn; with as="ul" the wrappers are list items.
- Is it bad for accessibility?
- Content is in the DOM from the start, and with reduced motion enabled it shows immediately without animating.