caliper uidocs

Scroll effects

Free

Tools for effects that follow scroll position, such as progress and reveals.

Installs components/ui/scroll-effects.tsxDepends on none beyond ReactMotion honours reduced motion
pnpm dlx shadcn@latest add https://caliperui.site/r/scroll-effects.json

Designing for the quiet middle

Most of a product's life is ordinary use. Motion should explain what changed and then get out of the way.

When to use #

Use it for

  • Adding a reading progress bar or a reveal on scroll.

Skip it when

  • Effects would distract from reading.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/scroll-effects.json

Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above. It is built from ScrollEffect, ScrollProgress and useScrollVars.

example.tsx
import { useRef } from "react"
import { ScrollEffect } from "@/components/ui/scroll-effects"

export function ScrollEffectsDemo() {
  const scroller = useRef<HTMLDivElement>(null);
  return (
    <ScrollEffect root={scroller} effect="fade-up">
                  <h4 className="text-xl font-semibold tracking-tight">Designing for the quiet middle</h4>
                  <p className="mt-2 text-sm leading-6 text-muted-foreground">Most of a product&apos;s life is ordinary use. Motion should explain what changed and then get out of the way.</p>
                </ScrollEffect>
  );
}

API reference #

ScrollEffect

component
PropTypeDefaultDescription
children *ReactNode—
effect"clip" | "scale" | "fade-up" | "parallax""fade-up"
rootRefObject<HTMLElement | null>—A scrollable ancestor to measure against. Omit to use the window.
asElementType"div"
classNamestring—

ScrollProgress

component
PropTypeDefault
targetRefObject<HTMLElement | null>—
classNamestring—

useScrollVars

component

No props of its own; it re-exports a primitive and takes that primitive’s props.

Accessibility #

It is built on native elements and keeps aria-hidden in step with state.

No custom key handling; Tab and the native activation keys do the work.

Motion #

It checks prefers-reduced-motion itself and settles immediately instead of travelling. Every state is still reachable.