Definition
This is the structure to reach for when you want a landing page where scrolling down unfolds the screen like a story — "stage 1 → stage 2 → stage 3" — without a heavy animation library. The core idea is to use how far you've scrolled (progress) as the playback timeline of the story.
More precisely, a scroll-driven narrative layout is a page structure that uses scroll progress as a narrative timeline. Inside a tall wrapper you place a position: sticky (a CSS layout that pins to a fixed spot on screen even as you scroll) stage, and you synchronize stage transitions, progress indicators, and element reveals with scroll() / view() timelines (a CSS feature that ties scroll position and an element's entry into the viewport to animation playback), animation-timeline, and pure CSS @keyframes (the syntax for defining time-based animation steps in CSS). You can build a product story like "Before → During → After" without JS animation libraries such as GSAP, Lenis, or Framer Motion.
Why it matters
Landing, onboarding, and tech-blog home pages have to persuade through several stages within one page. JS scroll libraries add bundle, hydration (the process where React attaches events to server-generated HTML to make it actually work), and main-thread cost, and the prefers-reduced-motion (a CSS media query that detects whether the user has turned on "reduce motion" in the OS) fallback gets complicated. In 2026, buzzy startup landings (Granola, Browserbase, etc.) produce a "living product" feel with the scroll-timeline + DOM demo combination. Compared to an mp4 hero, the text stays crisp and it's easy to align frame-by-frame with the scroll.
How it works
Split it into two layers.
1) Sticky scrollytelling (section transitions)
Read scroll progress p ∈ [0,1] via a JS scroll listener or animation-timeline: scroll(), then pick phase = floor(p × stageCount). If the wrapper height is stageCount × 100vh, you advance one stage per screen.
| Element | Role |
|---|---|
| tall wrapper | secures the scroll "timeline" |
| sticky stage | pins the visual frame — only content swaps |
| phase rail | anchors the current stage / next CTA as text |
| reduced motion | unpin sticky, list all stages statically |
2) Pure CSS loop demo (hero slot)
Like a live-notes demo on the right of the hero, a 14s looping sequence uses only keyframes, no JS.
- Reserve space: animate only
min-height+opacity/transform— no DOM insertion → CLS (Cumulative Layout Shift, a metric of how much elements shift and shake the screen during load) 0 - Typing:
clip-path: inset()+steps()wipe — safe even for Korean at the glyph level - Promotion sequence: TIL card → connector line → Knowledge card via sequential
animation-delay - reduced motion: fixed to the final state (promotion complete)
3) View entry (auxiliary layer)
Lists and cards reveal via view-reveal inside @supports (animation-timeline: view()). Independent of the scroll narrative — unsupported browsers show them immediately.
Practical application
Checklist:
- No
overflow: hiddenon the sticky parent — sticky dies. - Demo gets
aria-hidden+ real links stay separate — decouple decorative UI from the navigation contract. - Phase transitions use transition, loop demos use keyframes — don't mix the roles.
- Static fallback when motion is reduced — list the stages with no loss of information.
Tradeoffs
| Choice | Benefit | Cost |
|---|---|---|
| CSS scroll-timeline | 0kb, compositor-friendly (the render stage that composites on the GPU without layout reflow) | needs a fallback for Safari · older browsers |
| sticky + JS phase | precise control, links · focus possible | scroll listener or rAF cost |
| pure CSS loop demo | 0 hydration, crisp text | timing tuning is scattered across CSS |
| mp4 hero | fast to produce | heavy, hard to sync with scroll |
When not to use
- When content is short and there's no room to scroll — only sticky remains and the sequence breaks.
- Forms · payment flows where accessibility is critical — don't tie UI state to scroll.
- When SEO body text hides behind the scroll — key sentences appear late for crawlers and low-bandwidth users.
Common mistakes
overflow: hiddenon a sticky ancestor — the stage vanishes along with the scroll.- Wrapping demo text in a
<Link>— conflicts with the Playwright · screen-reader contract. - Not handling
prefers-reduced-motion— the fatigue of a 14s loop spinning forever. - Double-syncing a video demo + scroll-timeline — frame drift.
Related concepts
- 2026-startup-landing-page-trends — measured Granola · Browserbase patterns
- cls-skeleton-layout-reservation — demo space reservation and CLS
- largest-contentful-paint — hero asset strategy (DOM vs video)