滚动条驱动的动画是一个新的 CSS 特性,已经在部分现代浏览器中实现了,我们以前要实现滚动条动画效果时,可以使用一些 Javascript 库来实现,例如 ScrollMagicGsap 等动画库,现在 CSS 也可以实现一些基本的滚动驱动动画功能了。

dceea451-7119-41e9-b4e0-96766f3440fc.gif

CSS 滚动动画例子

我们先来看看一个简单的 CSS 滚动驱动动画的例子。

See the Pen css scroll-timeline by imkelen (@imkelen) on CodePen.

@keyframes appear {
  from {
    opacity: 0;
    scale: 0.8;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

img {
  animation: appear linear;
  animation-timeline: view();
  animation-range: entry 0% cover 50%;
}

animation-timeline 意思是在 img 元素出现在视图的时候触发。

animation-range 意思是动画在 img 元素进入视口的 0% 时开始,并在视口显示 img 元素的 50% 时完成。

通过上面例子可以看出,当图片开始出现在视图,图片开始触发 appear 动画,这时候样式是 opacity: 0; scale: 0.8 ,随着向下滚动,图片的样式会变成 opacity: 1; scale: 1

animation-timeline

animation-timeline 用来实现滚动条动画时间轴的来源,语法如下:

animation-timeline: <timeline-name>;

timeline-name 的枚举值有:

  • none:动画没有关联到任何时间线。
  • auto :动画关联到文档的默认时间线(DocumentTimeline)。默认情况下,时间线是与页面加载的时间相关联的。
  • scroll() :动画时间线和滚动条关联,基于祖先滚动容器的滚动进度来驱动动画。
  • view():动画时间线和当前元素的可见性(视口中的位置)相关联。

scroll()

上面介绍了 view() 的用法,接下来介绍下 scroll() 的用法,直接上代码:

.scroll-container {
  width: 400px;
  height: 400px;
  overflow: auto;
  border: 2px solid #000;
  position: relative;
}

.horizontal div {
  width: 800px;
  height: 100%;
  background: linear-gradient(to right, #f06, #4a90e2);
}

.horizontal img {
  position: absolute;
  width: 200px;
  height: 200px;
  left: 50%;
  display: block;
  border: 2px solid #000;
  transform-origin: center;
  animation: horizontalRotate 1s linear;
  animation-timeline: scroll(x);
}

@keyframes horizontalRotate {
  0% {
    transform: rotateY(0deg);
  }

  100% {
    transform: rotateY(360deg);
  }
}

这里定义了一个容器元素 scroll-container,div 元素是个配角,主要使容器可以横向滚动,我们重点关注 img 元素,这里设置了 animation-timeline: scroll(x) 使其可以响应父元素的横向滚动来执行动画效果。

注意这里的容器元素必须要设置 position: relative ,img 元素才可以找到根据父元素滚动驱动动画。 scroll() 不设置则默认响应纵向滚动条的滚动效果。

最终效果可以自己在 Codepen 查看:

See the Pen css scroll-timeline: scroll() by imkelen (@imkelen) on CodePen.

浏览器支持情况

截至 2024 年 12 月,浏览器的支持情况如下,暂时还不可以应用到生产环境中。

4f8e37c8-8fd8-41f4-8dc3-47b3a427ee78.webp

我们可以使用 @supports 规则来检测浏览器的支持情况来写 animation-timeline 语法,语法如下:

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* 编写驱动动画 */
  }
}

总的来说,能使用 CSS 实现滚动驱动动画,对代码的实现以及性能都有很大的好处。未来浏览器会支持更多的新特性来实现复杂的滚动驱动动画,例如 scroll-start-target 等。