useScrollIntoView
A custom React hook that handles scroll behavior for any scrollable element with animation and reduced-motion support.
useScrollIntoView
is a custom React hook that provides smooth scrolling functionality to any element. It works similarly to the native element.scrollIntoView()
method but with enhanced features including automatic reduced-motion detection and customizable scroll behavior.
Example
Loading...
Install
npx shadcn@latest add https://unlogg.com/r/use-scroll-into-view.json
pnpm dlx shadcn@latest add https://unlogg.com/r/use-scroll-into-view.json
bunx shadcn@latest add https://unlogg.com/r/use-scroll-into-view.json
Notes
- Automatically respects
prefers-reduced-motion
user preference - Uses
requestAnimationFrame
for smooth execution - Provides cancel functionality for ongoing scroll animations
- Works with any scrollable container
- Supports all native
scrollIntoView
options
API Reference
Parameters
Prop | Type | Default |
---|---|---|
options.inline? | 'start' | 'center' | 'end' | 'nearest' | 'nearest' |
options.block? | 'start' | 'center' | 'end' | 'nearest' | 'start' |
options.behavior? | 'auto' | 'smooth' | 'smooth' |
options? | ScrollIntoViewOptions | { behavior: 'smooth', block: 'start', inline: 'nearest' } |
Returns
Prop | Type | Default |
---|---|---|
handlers.cancel? | () => void | - |
handlers.scrollIntoView? | (options?: ScrollIntoViewOptions) => void | - |
handlers? | UseScrollIntoViewReturn | - |
ref? | React.RefObject<T | null> | - |
Usage
import { useScrollIntoView } from "@/hooks/use-scroll-into-view";
function ScrollExample() {
const [targetRef, { scrollIntoView }] = useScrollIntoView({
behavior: "smooth",
block: "center",
});
return (
<div>
<button onClick={() => scrollIntoView()}>
Scroll to target
</button>
<div style={{ height: "200vh" }}>
<div ref={targetRef}>Target element</div>
</div>
</div>
);
}
Advanced Usage
Navigation Menu
function NavigationMenu() {
const [homeRef, { scrollIntoView: scrollToHome }] = useScrollIntoView({
behavior: "smooth",
block: "start",
});
const [aboutRef, { scrollIntoView: scrollToAbout }] = useScrollIntoView({
behavior: "smooth",
block: "center",
});
return (
<div>
<nav>
<button onClick={() => scrollToHome()}>Home</button>
<button onClick={() => scrollToAbout()}>About</button>
</nav>
<section ref={homeRef}>Home Content</section>
<section ref={aboutRef}>About Content</section>
</div>
);
}
Override Options
function FlexibleScroll() {
const [targetRef, { scrollIntoView }] = useScrollIntoView();
return (
<div>
<button
onClick={() => scrollIntoView({ behavior: "auto", block: "start" })}
>
Instant scroll to top
</button>
<button
onClick={() => scrollIntoView({ behavior: "smooth", block: "center" })}
>
Smooth scroll to center
</button>
<div ref={targetRef}>Target</div>
</div>
);
}
With Scroll Cancellation
function CancellableScroll() {
const [targetRef, { scrollIntoView, cancel }] = useScrollIntoView();
const handleSlowScroll = () => {
scrollIntoView({ behavior: "smooth" });
// Cancel after 1 second if needed
setTimeout(() => {
cancel();
}, 1000);
};
return (
<div>
<button onClick={handleSlowScroll}>Start scroll</button>
<button onClick={cancel}>Cancel scroll</button>
<div ref={targetRef}>Target</div>
</div>
);
}
Accessibility
The hook automatically respects the user's prefers-reduced-motion
setting:
- When
prefers-reduced-motion: reduce
is set, smooth scrolling is automatically disabled - All scroll animations become instant (
behavior: "auto"
) - This ensures a comfortable experience for users with motion sensitivity
Use Cases
- Single Page Navigation: Create smooth scrolling between sections
- Documentation Sites: Table of contents navigation
- Landing Pages: Smooth scrolling to different sections
- Form Navigation: Jump to form sections or error fields
- Image Galleries: Navigate between gallery items
- Timeline Components: Scroll to specific timeline events
- Chat Applications: Scroll to latest messages or specific conversations
- Data Tables: Scroll to specific rows or columns