Frontend Lab
← 回到所有效果
G04S104gsap

Scrollytelling

滾動敘事

難度 ★★★★標籤 scrollTrigger · storytelling · sticky3 min read

效果簡述

左/上方 sticky 視覺、右/下方文字章節滾動。滾到不同章節時,視覺 換內容。是 NYT、Bloomberg、Pudding 那種長篇報導的核心招式。

🎨
1
設計階段 — 滾到這時上方圖示換
2
開發階段 — 滾到這時上方圖示換
3
上線階段 — 滾到這時上方圖示換
預設|左圖右文同步

Claude Code Prompt

💬 Claude Code Prompt
參考:S104 scrollytelling
技術:sticky 視覺 + ScrollTrigger onToggle 偵測當前章節

具體行為:
- 左欄(或上方)sticky top-0,放圖 / 數據 / 視覺
- 右欄(或下方)為章節文字
- gsap.utils.toArray('.chapter').forEach((el, i) => ScrollTrigger.create({ trigger: el, start: 'top 60%', end: 'bottom 60%', onToggle: ({ isActive }) => isActive && setStep(i) }))
- step 變動時切換視覺內容

限制:
- 章節 < 6 個(多了使用者會迷失)
- 視覺切換用 fade,不要硬切
- 行動上 sticky 上方視覺 + 內容下方滾比較自然

完整程式碼

Scrollytelling.tsx
'use client'

import gsap from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { useEffect, useRef, useState } from 'react'

export function Scrollytelling() {
const [step, setStep] = useState(0)
const root = useRef<HTMLDivElement>(null)

useEffect(() => {
  gsap.registerPlugin(ScrollTrigger)
  const ctx = gsap.context(() => {
    gsap.utils.toArray<HTMLElement>('.chapter').forEach((el, i) => {
      ScrollTrigger.create({
        trigger: el,
        start: 'top 60%',
        end: 'bottom 60%',
        onToggle: ({ isActive }) => isActive && setStep(i),
      })
    })
  }, root)
  return () => ctx.revert()
}, [])

return (
  <section ref={root} className="grid grid-cols-2 gap-8">
    <div className="sticky top-0 h-screen">{/* 視覺,根據 step 切換 */}</div>
    <div className="space-y-[60vh]">
      <div className="chapter">章節 1</div>
      <div className="chapter">章節 2</div>
      <div className="chapter">章節 3</div>
    </div>
  </section>
)
}

何時用

  • ✅ 長篇報導 / 案例研究
  • ✅ 產品操作說明(每步配視覺)
  • ✅ 數據敘事(地圖、圖表逐步揭露)

何時別用

  • ❌ 一般行銷頁(多到難駕馭)
  • ❌ 章節彼此沒關聯(拆成短篇還比較好)
  • ❌ SEO 重要 + 行動使用者多

我踩過的坑

  1. onToggle 切太快:start/end 區間重疊時,兩個章節都 active, step 跳來跳去。一定要把區間設成不重疊。

  2. 手機 sticky 高度問題:100vh sticky 上方時內容看不到。 mobile 用 50vh 上方視覺 + 下方滾比較合理。

  3. 章節切換沒過渡:onToggle 直接 setState 視覺硬切。在視覺 元件加 fade 過渡或 motion 過場。

相關效果

搜尋

按 ⌘K 隨時開啟