页面滚动进度条特效(自研 JS,颜色/高度/位置实时可调)

JSCSS 许可:自研原创

页面滚动进度条:监听滚动计算阅读进度,顶部/底部位置可选,颜色与高度实时可调,渐变高亮质感,支持页面滚动与任意容器滚动,零依赖。

效果演示(真实可交互)

🎯 拖动下方滚动条:顶部进度条实时反映阅读进度

《前端动效设计原则》节选

滚动进度条是长页面最直观的导航反馈之一,它告诉用户「你读到哪了、还有多少」。本文选自粤喵组件站文档,用于演示滚动进度条的真实效果。

第一条原则:反馈即时。进度条必须与滚动位置严格同步,任何延迟都会让用户失去信任感。实现上只需监听 scroll 事件(或使用被动监听器),计算 scrollTop / (scrollHeight - clientHeight) 即可得到 0-100% 的进度。

第二条原则:视觉克制。进度条默认宽度很细(2-6px),只在靠近时才出现高亮;颜色通常与品牌色一致,也可以做成渐变色增加质感。过度设计的进度条会抢走内容本身的注意力。

第三条原则:性能友好。滚动事件高频触发,应避免在回调里做重计算和 DOM 写操作。推荐做法:回调里只更新 CSS 变量或 transform,把绘制交给浏览器合成器,或使用 requestAnimationFrame 节流。

第四条原则:移动端适配。触屏滚动与桌面滚轮事件行为一致,都是 scroll 事件,因此同一套代码即可覆盖。需要注意 iOS 橡皮筋效果下 scrollTop 可能为负,要做 Math.max(0, ...) 保护。

第五条原则:多容器场景。除了整页滚动,模态框、侧边栏、表格等内部滚动容器同样适用,只需把监听对象换成对应元素即可。本演示就是把「页面」替换成了一个可滚动的 div。

第六条原则:可访问性。进度条是装饰性元素,应添加 aria-hidden="true" 避免被屏幕阅读器朗读;如确需传达进度,请使用带 role="progressbar" 的语义化实现。

演示区用内嵌滚动容器模拟长页面;正式使用时代码不变,只需把监听对象从容器换成 window 或 document.documentElement。

完整代码

<div class="progress-bar" id="progressBar"></div>
<!-- 长页面内容省略 -->
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 0%;
  height: 5px;
  background: linear-gradient(90deg, #6c8cff, #a96cff, #ff8ecf);
  box-shadow: 0 0 10px rgba(108, 140, 255, .6);
  z-index: 9999;
}
const bar = document.getElementById('progressBar');

function update() {
  const doc = document.documentElement;
  const max = doc.scrollHeight - doc.clientHeight;
  const pct = max > 0 ? doc.scrollTop / max : 0;
  bar.style.width = (pct * 100).toFixed(2) + '%';
}
window.addEventListener('scroll', update, { passive: true });
window.addEventListener('resize', update);
update();

核心公式只有一行:进度 = scrollTop / (scrollHeight - clientHeight)。容器内滚动(模态框/侧边栏)时,把 doc 换成 容器元素、window 换成容器即可。

参数说明

参数位置说明
颜色background: linear-gradient(...)渐变三色或品牌单色
高度height: 5px2-12px,越细越精致
位置top: 0 / bottom: 0固定顶部或底部,随需求切换
监听对象window / 容器元素整页滚动或局部容器滚动
更新时机scroll + resize必须同时监听 resize,否则窗口变化后进度不准

兼容性与性能

常见问题

Q: 和现成的进度条库比有必要自研吗? 完全没必要用库。整个功能只有一行核心公式,第三方库反而引入体积与版本风险;本组件为粤喵自研,含演示共约 30 行代码。

Q: 在 iOS Safari 上进度条会跳吗? iOS 的橡皮筋回弹会让 scrollTop 短暂为负,建议在公式外包裹 Math.max(0, ...);本组件演示中的容器滚动同样适用该保护。

Q: 如何把进度条放进某个区块而不是全屏固定? 把 position: fixed 改为 position: sticky; top: 0,并把滚动监听目标换成该区块的滚动容器即可;块内进度条常用于文章页、文档站。

Q: 可以商用吗? 可以。本组件为粤喵自研原创代码,免费商用无需署名,无任何协议限制。

许可与来源

  • 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
  • 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
  • 首次发布:2026-09-01 · 最近更新:2026-09-01
  • 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
  • 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理

常见问题

这个组件可以商用吗?

可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。

浏览器兼容性如何?

支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。

怎么修改动画参数?

直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。

✍️ 作者与审核