Frontend Lab
← 回到所有效果
F11S002framer-motion

Scroll Progress Bar

滾動進度條

難度 ★★★★★標籤 滾動 · 進度 · useScroll2 min read

效果簡述

固定在頁面頂端的細條,隨著使用者滾動填滿。長文章、教學頁很常見, 讓人知道「還剩多少」。

↓ 實際 page 進度示意(loop 演示)· 位置:top · 高度 2px

預設|頂部 2px 主色條

Claude Code Prompt

💬 Claude Code Prompt
參考:S002 scroll progress bar
技術:Framer Motion useScroll + useSpring(讓動畫平滑)

具體行為:
- useScroll() 拿 scrollYProgress(0 → 1)
- 用 useSpring 包一層讓進度平滑:useSpring(scrollYProgress, { stiffness: 100, damping: 30, restDelta: 0.001 })
- motion.div 固定 top-0 left-0 right-0 高度 2-3px
- style={{ scaleX, transformOrigin: '0%' }}

限制:
- 高度不要超過 4px(細條才不打擾閱讀)
- 顏色用 accent,跟主標題 / Hero 區別開
- 不要套在所有頁面,只放長內容頁

完整程式碼

ScrollProgressBar.tsx
'use client'

import { motion, useScroll, useSpring } from 'framer-motion'

export function ScrollProgressBar() {
const { scrollYProgress } = useScroll()
const scaleX = useSpring(scrollYProgress, {
  stiffness: 100,
  damping: 30,
  restDelta: 0.001,
})

return (
  <motion.div
    style={{ scaleX, transformOrigin: '0%' }}
    className="fixed top-0 left-0 right-0 z-50 h-[3px] bg-lab-accent"
  />
)
}

何時用

  • ✅ 長部落格文章
  • ✅ 教學 / docs 頁
  • ✅ 案例研究的單頁版

何時別用

  • ❌ 短頁面(沒進度可顯示)
  • ❌ 首頁、Landing(搶焦點)
  • ❌ 已有 sidebar TOC 的頁(資訊冗餘)

我踩過的坑

  1. 沒包 useSpring 會頓:直接把 scrollYProgress 當 scaleX 會跟著 每一個 wheel event 跳,視覺像「卡卡的」。useSpring 平滑後才像 專業作品。

  2. iOS Safari 上 -webkit-overflow-scrolling 會打亂:若父層有 -webkit-overflow-scrolling: touch,useScroll 可能拿不到正確值。 把進度條放 body 直接子層最穩。

相關效果

搜尋

按 ⌘K 隨時開啟