scroll-timeline仅支持单元素滚动进度映射,不支持状态联动或条件触发;需用js协调或css伪类间接实现“关联”,且必须绑定到有明确滚动上下文的非根容器。

scroll-timeline 目前不能直接用于创建“关联动画”——它不支持元素间状态联动或条件触发,只能把单个动画的进度线性映射到滚动位置。所谓“关联”,必须靠 JS 协调或 CSS 伪类 + 属性继承间接实现。
scroll-timeline 绑定动画时为什么看不到效果
常见错误是直接在 body 或 html 上尝试绑定,但规范明确要求:滚动容器必须是具有明确滚动上下文的元素(overflow: scroll / auto),且不能是根容器本身(root 在部分浏览器中行为异常)。Chrome 125+ 虽默认启用,但若父级没设高度、没触发滚动,animation-timeline: scroll() 就会静默失效。
- 确保滚动容器有固定高度(如
height: 100vh)和overflow-y: scroll - 避免在
body上直接使用scroll(root y);改用scroll(nearest block)或显式命名时间线 - 检查 DevTools 的 Animations 面板:若 timeline 显示为 “(none)”,说明容器未被识别为有效 scroller
@scroll-timeline 规则里 axis 和 source 的取值差异
@scroll-timeline 是声明式定义时间线的唯一方式,scroll() 函数只是快捷语法。二者关键区别在于可控粒度:
-
axis: y表示垂直滚动(对应block),axis: x表示水平滚动(对应inline),混用会导致动画卡在 0% 或 100% -
source: selector(...)可指定任意滚动容器(如source: #scroller),但该元素必须已存在于 DOM 且可滚动;不支持动态插入后补绑定 -
start: 0%/end: 100%默认以容器滚动范围为全程,若想让动画只在某段区域触发,需写成start: 20%/end: 80%
示例:
@scroll-timeline slide-in {
source: #main-scroller;
axis: y;
start: 10%;
end: 90%;
}然后在元素上写 animation-timeline: slide-in;
多个元素共享同一滚动进度但表现不同动画
这是唯一能接近“关联”的纯 CSS 方式:所有元素共用同一个 @scroll-timeline,但通过 animation-delay、animation-duration 或 @keyframes 关键帧偏移制造错峰效果。
- 不要试图用
:has()或兄弟选择器控制其他元素——scroll-timeline不触发重绘或状态变更 - 若需“一个动、另一个反向动”,可在同一 timeline 下设置两个
@keyframes,一个用from/to,另一个用0%, 100%配合transform: scaleX(-1)模拟镜像 - 性能提示:每个绑定
animation-timeline的元素都会独立采样滚动位置,10 个以上建议用 JS 合并监听,避免合成层压力
为什么 scroll-timeline 无法响应“滚动到底”这类逻辑判断
它本质是插值器,不是事件系统。你无法从中读取 scrollLeft、scrollTop 或触发 scrollend,也无法生成类似 :is(:scrolled-past-50%) 的伪类。所有“条件行为”(比如滚过某区域才显示按钮)都必须回退到 JS。
- Firefox 仍需手动开启
layout.css.scroll-driven-animations.enabled标志,且仅支持基础属性(opacity,transform),background-color等会降级为时间动画 - Safari 完全忽略
@scroll-timeline和animation-timeline,连 warning 都不报——别依赖它做核心交互 - 真正需要“关联响应”的场景(如导航高亮 + 内容淡入 + 进度条同步),目前只有 JS +
requestAnimationFrame+getBoundingClientRect()这一套组合最可靠
复杂点不在写法,而在于误判了它的能力边界:它解决的是“怎么动”,不是“什么时候动”或“动完之后干什么”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











