教程

用 CSS Scroll-Driven 动画实现滚动触发的视觉反馈

用 CSS Scroll-Driven 动画实现滚动触发的视觉反馈

适合有一定 CSS 基础的前端开发者,学习如何用原生 CSS 实现滚动时自动触发的动画效果,无需 JavaScript。使用 animation-timeline 和 animation-range 等新属性,打造流畅的视差、渐显、滑入等交互体验。

第 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` 实现更精细的滚动动画控制

参考来源

  1. Scroll-Driven Animations Josh W. Comeau · Josh W. Comeau

封面为 NicePSD 原创示意图,未使用原文图片。原创声明:本文由 NicePSD 基于海外公开资料整理、消化并重写,观点归原作者所有,详细内容请阅读参考原文。转载请注明出处。

更多前沿文章