npm install @caustics/scroll-reveal <script> import { ScrollReveal } from '@caustics/scroll-reveal'; </script> <ScrollReveal preset="subtle" />
npm install @caustics/scroll-reveal import { ScrollReveal } from '@caustics/scroll-reveal/react'; return <ScrollReveal preset="subtle" />;
npm install @caustics/scroll-reveal import { mount } from '@caustics/scroll-reveal'; mount(document.querySelector('#hero'), { preset: 'subtle' });
| Prop | Type | Default | Description |
|---|---|---|---|
| preset | string | "subtle" | Named preset. Overrides individual props when set. |
| colors | string[] | undefined | Override palette. Accepts hex, hsl, or CSS custom properties. |
| reducedMotion | 'pause' | 'static' | 'pause' | Behavior when prefers-reduced-motion is active. |
| class | string | undefined | Additional CSS classes applied to the root element. |
caustics-scroll-reveal/ ├── svelte/ ScrollReveal.svelte · index.ts · types.ts ├── react/ ScrollReveal.tsx · index.ts · types.ts ├── vanilla/ scroll-reveal.ts · compiled .js ├── docs/ README.md · API.md · CHANGELOG.md ├── LICENSE.md Caustics Commercial License └── package.json
Scroll Reveal uses the IntersectionObserver API for scroll detection — no scroll listeners, no per-frame requestAnimationFrame loop, no layout reads. Each reveal animates only opacity, transform (translate3d + scale), and filter: blur() via the Web Animations API: compositor-only properties that run off the main thread, so dozens of simultaneous reveals stay smooth at 60fps with no layout thrashing.
It is dependency-free — no GSAP, no runtime. The whole engine is roughly 4 KB gzipped.
Four presets: subtle (short fade + small slide up, fast — the default), dramatic (long blur-to-clear + scale, slow), grid-stagger (children reveal in sequence, with five ordering modes), and fade (pure opacity, no transform). Every preset field is overridable.
Stagger is built in: reveal a grid or list child-by-child with forward, reverse, center, edges, or random order, with an optional cap so the last item never arrives too late.
Accessibility is enforced, not optional. Under prefers-reduced-motion: reduce the default behaviour shows every element immediately at its final state — no motion, never hidden. The library is the only thing that ever hides [data-reveal] content, applied by JavaScript after it confirms IntersectionObserver support: if the script is blocked or fails, content was never hidden and renders normally (true progressive enhancement). Reveals only touch visual properties, so screen-reader text stays in the accessibility tree throughout.
Ships with vanilla (reveal() + zero-markup data-reveal auto-init with a MutationObserver for dynamic content), a Svelte 5 action and component, and a React hook and component — one engine behind all three.
Caustics Commercial License · lifetime updates within v1