第 1 步:理解滚动驱动动画的核心原理
传统动画基于时间,而滚动驱动动画将动画进度与页面滚动位置绑定。当元素进入视口时,动画开始随滚动推进,实现‘滚动即播放’的效果。这改变了我们对 @keyframes 的认知——百分比不再表示时间,而是滚动比例。
核心是设置 `animation-timeline: view()`,它让动画以视口中的元素位置作为输入,滚动距离直接映射到动画进度,实现平滑的视觉反馈。
第 2 步:控制动画的触发范围和时机
使用 `animation-range` 可以精确控制动画何时开始与结束。`contain` 从元素完全进入视口才开始,`entry` 从元素刚露头时启动,`exit` 则在元素离开视口时触发,适合做渐显渐隐效果。
若要同时实现进入时淡入、离开时淡出,可为同一元素设置多个动画,分别指定 `entry` 和 `exit` 范围,用逗号分隔动画属性值即可。
第 3 步:自定义动画的节奏与缓动效果
像普通动画一样,可使用 `cubic-bezier` 或 `linear()` 实现复杂的缓动曲线。`linear()` 支持弹簧类动画,可模拟真实物理运动,尽管使用需谨慎,避免过度干扰用户体验。
建议在设计时考虑 `prefers-reduced-motion` 媒体查询,为有运动敏感问题的用户提供关闭动画的选项,提升无障碍体验。
第 4 步:精确控制动画范围的起止点
通过 `animation-range-start` 和 `animation-range-end` 的长语法,可设定动画在滚动中精确的起止位置。例如 `cover 0%` 表示从元素进入视口开始,`cover 50%` 表示滚动到视口中点时结束。
此功能适合实现复杂的分段动画,如元素在滚动中分阶段出现或变换状态,增强动态层次感。
常见问题与注意事项
`animation-fill-mode: backwards` 是关键技巧,尤其在 `contain` 或 `entry` 范围下,确保动画起始状态提前应用,避免元素‘突然跳入’。
Firefox 目前仍需开启实验性标志 `layout.css.scroll-driven-animations.enabled` 才能使用,但其他主流浏览器支持良好,可放心在生产中使用。
要点速览
- 用 `animation-timeline: view()` 将滚动位置映射为动画进度,实现无 JS 的滚动动画
- 通过 `animation-range: entry` 或 `contain` 精确控制动画触发时机
- 使用 `animation-fill-mode: backwards` 确保起始状态提前生效
- 结合 `prefers-reduced-motion` 做无障碍优化,提升用户体验
- 用 `animation-range-start` 和 `animation-range-end` 实现更精细的滚动动画控制