Scroll-driven Animations 是为非脚本化异步动画设计的纯CSS方案,依赖滚动容器、scroll-margin锚点、animation-timeline绑定及animation-range切片,仅限合成属性以保障性能。

Scroll-driven Animations 本身就是为“非脚本化异步动画”而设计的——它不依赖 JavaScript,动画进度由浏览器在合成线程中根据滚动位置自动计算并驱动,天然异步且不阻塞主线程。
核心前提:确保滚动上下文有效
动画要随 DOM 滚动自然推进,必须满足三个硬性条件:
- 目标元素必须处于一个**真实可滚动的容器内**(如
div设置了overflow-y: scroll且内容高度超出容器高度);body或html作为滚动源在多数浏览器中不可靠,不推荐使用 - 该滚动容器需有明确尺寸(例如
height: 500px),不能是height: auto或受弹性布局动态挤压而无固定滚动范围 - 目标元素上必须设置
scroll-margin(如scroll-margin-top: 120px),用于锚定其在滚动时间轴上的起始触发点;否则浏览器无法确定“从哪开始算 0%”
声明式绑定:用 animation-timeline + scroll()
这是实现非脚本化的核心语法。无需 JS 监听、无需 requestAnimationFrame,仅靠 CSS 即可建立滚动与动画的映射关系:
-
animation-timeline: scroll();表示绑定到当前最近的可滚动祖先(即隐式根滚动时间线) - 若需更精确控制,可显式命名时间线:
animation-timeline: --my-timeline;,再配合@scroll-timeline --my-timeline { source: selector(.scroller); orientation: vertical; start: 0px; end: 400px; } - 注意:
@scroll-timeline规则必须在样式表中定义,且source必须指向一个已渲染、可滚动、有明确尺寸的 DOM 元素
控制播放区间:animation-range 精准切片
动画不该全程播放,而是随用户滚动“按需呈现”。用 animation-range 定义它在滚动轴上的生效段:
-
animation-range: entry 0% entry 100%;表示元素顶部刚进入视口时开始,到底部即将离开时结束 -
animation-range: 20% 80%;表示滚动进度到达整体 20% 时启动,80% 时完成(适用于固定高度容器内的相对定位) - 值支持
entry/exit关键字或绝对像素/百分比,但百分比基于 timeline 总长度(不是视口高度)
性能安全区:只用合成属性 + 隔离布局
所谓“异步”,前提是动画不触发重排(layout)和重绘(paint)。必须限制动画属性范围:
- 只使用能走合成层的属性:
opacity、transform(translate、scale、rotate),避免width、height、top、left等触发布局的属性 - 目标元素建议添加
will-change: transform;或设为position: absolute/position: fixed,使其脱离文档流,减少滚动时的样式计算负担 - 滚动容器自身应避免
overscroll-behavior: none或动态 height 变化,否则 timeline 会失效或抖动
只要滚动容器稳定、锚点明确、属性合规,整个动画流程就完全由浏览器自主调度——没有 JS 回调、没有帧率干预、没有同步等待,真正实现声明式、异步、零脚本的滚动驱动效果。










