scroll-timeline不能实现真正的实时滚动进度条,因其仅定义动画节奏映射而不暴露滚动百分比为可读/可绑定的值,动画一次性播放且无法回滚、暂停或响应动态内容重排,必须用js计算scrolltop/(scrollheight-clientheight)并注入css变量驱动transform: scalex()。

scroll-timeline 不能实现真正的“随滚动实时变化的进度条”,它只能驱动一次性的、不可逆的动画播放。想让进度条宽度精确跟随 scrollTop / (scrollHeight - clientHeight) 实时变化,必须用 JavaScript。
为什么 scroll-timeline 绑定 @keyframes 做不了进度条?
常见错误是写这样的代码:
@keyframes progress-fill { from { width: 0%; } to { width: 100%; } }
.progress-bar { animation: progress-fill linear; animation-timeline: scroll(root); }
结果发现:滚动到底后进度条卡在 100%,往上滚不缩回;中途停住就卡中间;无法读取当前值;动态加载内容后位置错乱。
-
scroll-timeline只定义动画“节奏映射”,不暴露滚动百分比为可读/可绑定的值 - 动画播完即停,没有暂停、回滚、重置机制
- 多个元素共用
scroll(root)时,各自起止位置按 DOM 物理位置算,不是统一文档高度基准 - 浏览器内部把滚动位移线性映射到关键帧 0%→100%,但这个映射结果无法被
width、transform等属性直接引用
animation-timeline: scroll() 的实际生效条件
哪怕你只想让它动起来,也得满足硬性前提:
- 滚动容器必须有明确滚动上下文:
overflow-y: scroll或auto,且内容溢出(height+overflow缺一不可) - 不要直接绑
body或html—— 多数浏览器不认,改用source: selector(#scroller)指向一个真实存在的块级容器 -
@scroll-timeline规则里source和orientation必须显式声明,orientation: vertical不能省略 -
start和end推荐用像素值(如start: 0px,end: 500px),用0%/100%在响应式或动态内容下容易偏移 -
animation-duration必须存在(哪怕设成1s),否则 Chrome 会静默降级为时间驱动动画
真能用 CSS 实现的“类进度条”效果有哪些?
如果你接受单向、不可逆、仅视觉示意的效果,可以这样用:
- 给固定区域内的容器加滚动条,用
@scroll-timeline驱动其内部元素淡入/滑入 —— 这是它最稳的用法 - 多个元素共享同一时间线,靠
animation-delay或@keyframes关键帧偏移制造错峰入场,模拟“渐进感” - 用
transform: scaleX(-1)+ 同一 timeline 实现镜像反向动画,但仍是单向播放 - 配合
animation-range: entry 20% exit 80%控制触发区间,避免顶部突兀出现
注意:animation-range 是基于元素在视口中的可见比例(view-timeline 行为),和 @scroll-timeline 的 start/end 不是一回事,别混用。
真正要实时进度条,JS 怎么写才轻量可靠?
核心就是两行:
document.addEventListener('scroll', () => {
const progress = window.scrollY / (document.body.scrollHeight - window.innerHeight);
document.documentElement.style.setProperty('--scroll-progress', progress);
});
然后 CSS 里:
.progress-bar { transform: scaleX(var(--scroll-progress)); }
- 用
requestIdleCallback或throttle包一层更稳妥,但简单页面直接监听也够用 - 务必用
document.documentElement.style.setProperty,不要操作style属性,避免内联样式污染 - 初始值要在 CSS 里设好:
--scroll-progress: 0;,否则首次渲染可能空白 - 动态内容插入后,记得重新计算
scrollHeight,否则进度条会不准
真正麻烦的从来不是怎么写,而是滚动容器不是 window、内容高度频繁变化、或者需要兼容 Safari/Firefox —— 这些时候,scroll-timeline 根本不工作,JS 反而是唯一解。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











