scroll-timeline 不是滚动监听器,仅将滚动位移映射为0%→100%时间轴供CSS动画使用;无法读取scrollTop、判断方向或执行JS逻辑,其核心职责仅为绑定动画节奏。

scroll-timeline 不是监听器,它不触发回调也不暴露滚动值
直接说结论:scroll-timeline 不能“监听”滚动,它只是把滚动位移映射成一个 0% → 100% 的时间轴,供 @keyframes 动画消费。你无法用它读取当前 scrollTop、判断方向、获取速度,也不能在某个滚动点执行 JS 逻辑。
常见误解是把它当 IntersectionObserver 或 scroll 事件替代品——它不是。它的职责非常窄:绑定动画节奏。
- 想“检测是否滚动中”?得用 JS 的
requestAnimationFrame+ 上一帧scrollY差值,或 CSS 的@scroll-timeline配合变量动画(但仅限视觉反馈) - 想“滚动到某位置执行函数”?必须用
IntersectionObserver或scroll事件 - 想“实时更新进度条宽度”?
scroll-timeline无法回滚,必须用 JS 计算并写入style.width或 CSS 变量
animation-timeline: scroll() 的生效硬性条件
哪怕只写一行 animation-timeline: scroll();,也必须同时满足三个底层条件,缺一不可,否则静默失效:
- 滚动容器要有明确的滚动上下文:
overflow-y: auto或scroll,且内容高度 > 容器高度(height+overflow缺一不可) - 不能直接绑在
body或html上——多数浏览器不认;推荐显式用scroll(#scroller)指向一个真实存在的块级元素 -
scroll()函数的参数必须完整:比如scroll(root block)中的block(垂直方向)不能省略,Safari 和 Chrome 都会因此忽略该声明
DevTools 的 Animations 面板里看不到时间轴?先检查这三条。别急着改动画代码。
立即学习“前端免费学习笔记(深入)”;
如何让元素“滚动到 60% 时淡入”,而不是“从 60% 开始动”
关键在 animation-range:它定义的是动画播放的**滚动区间**,不是触发点。设 60% 70% 表示:滚动进度从 60% 到 70% 之间,动画从 0% 执行到 100%。
若想“刚好在滚动到 60% 时完成显示”,实际做法是:
- 把区间缩窄:比如
animation-range: 59% 60% - 配极短动画时长:
animation-duration: 0.01s - 关键帧保持线性:
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } - 注意命名规范:
scroll-timeline-name: --my-scroller必须带双横线前缀,且在animation-timeline中严格一致
别指望靠 display: none/block 切换——它不可动画。用 opacity 或 transform 才行。
Chrome/Safari 支持了,但 Firefox 仍不可靠
截至 2026 年 9 月,scroll-timeline 在 Chromium 115+ 和 Safari 17.4+ 原生支持;Firefox 仍需 -moz-scroll-timeline 前缀,且实现不完整——比如 animation-range 的 entry/exit 关键字不识别,scroll(#id) 绑定常静默失败。
如果你的项目必须兼容 Firefox,目前没有纯 CSS 替代方案。要么降级为 IntersectionObserver + 类名切换,要么用 JS 监听 scroll 并更新 CSS 变量驱动动画。
真正容易被忽略的,是滚动容器的 height 和 overflow 必须同时存在——少了任意一个,整个机制就断在第一层,后面所有动画设置都白搭。


















