Featured image of post CSS 滚动驱动的动画:基于滚动的效果的未来Featured image of post CSS 滚动驱动的动画:基于滚动的效果的未来

CSS 滚动驱动的动画:基于滚动的效果的未来

探索 CSS 滚动驱动动画:滚动时间线、视图时间线、动画时间线、基于进度的关键帧、视差和滚动进度指示器。

JavaScript 滚动事件的问题

传统上,基于滚动的效果依赖于在主线程上运行的 JavaScript 滚动事件侦听器,这通常会导致卡顿、丢帧和糟糕的用户体验。即使有被动侦听器和 requestAnimationFrame 限制,布局抖动仍然是一个持续存在的问题。 CSS 滚动驱动动画通过将滚动跟踪移动到合成器线程来解决这个问题,从而实现流畅的 60fps 效果,而无需任何 JavaScript 开销。

关键概念

三个核心概念为该功能提供了动力。 滚动时间线 将动画链接到滚动容器的滚动位置。 视图时间轴将动画与滚动容器中元素的可见性联系起来。 animation-timeline 属性将命名动画绑定到任一时间线类型。使用 timeline-scope 在 DOM 树中的元素之间共享时间线。

滚动进度时间表

滚动进度时间线跟踪用户在容器中滚动的距离。现代方法使用 scroll-timeline 简写和内联 scroll() 函数:

@keyframes fill-progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.progress-bar {
  animation: fill-progress linear;
  animation-timeline: scroll();
}

scroll() 函数在最近的滚动容器上创建匿名时间线。对于命名时间线,请在滚动条上使用 scroll-timeline-namescroll-timeline-axis,然后使用 animation-timeline: --my-timeline 引用它。


查看进度时间表

视图时间线根据视口内的元素可见性触发动画。在观察到的元素上设置 view-timeline-name 并绑定动画:

@keyframes fade-in {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

.reveal {
  animation: fade-in linear;
  animation-timeline: view();
  animation-range: entry 0% cover 50%;
}

animation-range 属性控制动画何时开始和结束。范围名称包括 entry (元素进入)、exit (元素离开)、contain (完全在其中)和 cover (完全可见)。将它们结合起来可以精确控制时间。

实例:阅读进度指示器

当用户滚动时填充的固定进度条是最实际的应用之一:

body {
  scroll-timeline-name: --page-scroll;
}

.progress {
  position: fixed; top: 0; left: 0;
  height: 4px; z-index: 100;
  background: linear-gradient(90deg, #667eea, #764ba2);
  transform-origin: left center;
  animation: fill-progress linear;
  animation-timeline: --page-scroll;
}

实际示例:纯 CSS 视差

CSS 视差完全消除了 JavaScript。使用不同的 animation-range 值对多个元素进行分层以创建深度:

.layer-back { animation-range: entry 0% exit 100%; }
.layer-front { animation-range: entry 0% exit 50%; }

没有主线程布局重新计算,没有滚动事件监听器——只有 60fps 的平滑合成视差。


浏览器支持和渐进增强

浏览器版本状态
115+全力支持
野生动物园17.2+旗帜背后
火狐121+部分

使用 @supports 进行渐进增强:

@supports (animation-timeline: scroll()) {
  .progress { animation: fill-progress linear; animation-timeline: scroll(); }
}

首先提供静态后备,然后分层滚动驱动的动画作为支持浏览器的增强功能。

结论

CSS 滚动驱动动画代表了基于滚动的效果的范式转变。通过将滚动跟踪移至合成器线程,它们保证了平稳的性能,同时极大地简化了代码。随着浏览器支持的成熟,这些功能将成为创建引人入胜的高性能 Web 体验的重要工具。