Hooks/UI & DOM/useScrollIntoView

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

PropTypeDefault
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

PropTypeDefault
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

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