Scroll Storytelling
A narrative design technique where content, animations, and transitions unfold in sequence as the user scrolls — turning a page into a guided story.
Plain English
Scroll storytelling treats the vertical scroll axis as a timeline for a narrative. Instead of presenting all content at once, the page parcels information out beat by beat: a headline fades in, then a supporting visual slides up, then a statistic counts up as the user continues scrolling. The technique is defined by two structural patterns — scroll-triggered reveals (elements animate in as they enter the viewport) and pinned scroll sequences (the page "pauses" while animation plays out over a long scroll distance, then unpins and continues). Apple's product pages are the canonical reference: a MacBook lid opens as you scroll, the chip diagram animates in stages, and key specs appear one at a time. The effect creates focus — each scroll beat controls what the reader sees, preventing cognitive overload by rationing information.
Technical
Implementation requires either GSAP ScrollTrigger (most capable: pin: true, scrub: 1, start: "top top") or CSS Scroll-Driven Animations for simpler reveals. A pinned section works by setting position: sticky on a container with a tall scroll-height wrapper (height: 500vh for a 5-beat sequence). ScrollTrigger's scrub ties animation progress directly to scroll progress (scrub: 1 = 1s lag). For pure CSS: animation-timeline: view() on each element with staggered animation-range values. IntersectionObserver is the lightweight JS fallback. Key consideration: pinned scroll is jarring on mobile where momentum scrolling conflicts with the pin — use a non-pinned, stagger-reveal approach on small screens via matchMedia.
Live Demo
Scroll Storytelling
In a real page, each chapter would reveal on scroll. Click below to advance through the narrative.
Users are lost.
Without clear structure, visitors scan pages randomly, miss key information, and leave frustrated. The homepage has no narrative — just a wall of content.
Chapter 1 — The Problem
Each scroll reveal should answer a question the user is just starting to form.
Usage
✓ Good usage
A product landing page that pins a phone mockup in the center while the user scrolls through four feature highlights — each scroll beat replaces the screen content and animates a descriptive label in from the side.
✗ Bad usage
A blog post that gates every paragraph behind a scroll trigger — forcing users to scroll continuously just to read text is a usability antipattern that breaks page search (Ctrl+F) and reading flow.
Recommended values
- Pinned sequence wrapper height: 200–500vh depending on beat count
- GSAP scrub value: 0.5–2 (lower = snappier response to scroll)
- Reveal threshold: IntersectionObserver rootMargin "-10% 0px"
- Beat spacing: one major reveal per ~200–300px of scroll distance
- Mobile fallback: standard stagger-reveal, no pins
- Content density: 1 key idea per scroll beat maximum
Common mistakes
- Pinning on mobile — iOS momentum scrolling fights scroll-jacking, making pinned sequences feel broken and impossible to navigate predictably.
- No skip or non-animated path — users who have visited before or who need the content quickly must sit through the entire animation sequence with no way to jump ahead.
- Animating text content that changes mid-pin — text that morphs or is partially visible during scroll intermediate states creates illegible states that WCAG's animated content guidelines flag as problematic.
AI Prompt Example
Copy this into Claude, Cursor, Bolt, or v0.
Build a scroll storytelling section for the product page using GSAP ScrollTrigger. Create a 400vh tall wrapper div containing a sticky inner container. Pin the sticky container to the viewport. Animate three feature panels in sequence using scrub: 1 — each panel fades in over a 100vh scroll window then fades out before the next. Use matchMedia("(max-width: 768px)") to disable the pin on mobile and fall back to simple IntersectionObserver-triggered fade-ins instead.