C

CSS 的未来:滚动动画

2025-06-07

CSS 的未来:滚动动画

今天我们将探讨animation-timeline中基于滚动的动画。目前,如果要将动画关联到滚动,您必须监听 JS 中的 scroll 事件并更新样式,或者直接更新一些 CSS 变量。但很快我们将能够定义除已用秒/毫秒之外的时间轴。与以往一样,这些文章中对此功能的支持尚未真正实现,但正在逐步推广(本文撰写时,Chrome Canary 已支持此功能)。

页面沿 z 轴翻滚的演示

什么是动画时间轴?

从历史上看,动画的时间线是从动画开始到结束的时间量,您可能习惯于看到这样的内容。

.fade-element {
  animation: fade-animation-name 300ms linear;
}

@keyframes fade-animation-name {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}
Enter fullscreen mode Exit fullscreen mode

在这个动画中,动画一开始,.fade-element透明度从 0 变为 1 需要 300 毫秒。由于动画函数是线性的,我们知道,如果在 210 毫秒时观察这个动画,透明度应该是 0.7。研究不同的动画函数超出了本博客的讨论范围,但如果您希望我介绍一下,请告诉我。

想象一下,如果我们可以不再使用时间作为唯一的时间轴,而是使用屏幕上元素的百分比或滚动位置 400px 和 600px 之间的距离。

这就是动画时间轴的本质。我们使用了两个新的 CSS 属性,分别称为animation-timelineanimation-range

.fade-element {
  animation: fade-animation-name linear;
  animation-timeline: scroll();
  animation-range: 0 100vh;
}
Enter fullscreen mode Exit fullscreen mode

什么是滚动动画时间轴?

正如我们在上一节中提到的,滚动时间轴有两种类型:Scroll Progress TimelineView Progress Timeline

滚动进度时间轴

该时间线连接到容器的滚动位置,您可以选择哪个容器以及哪个轴。

要使用滚动时间轴,您必须将您的设置animation-timelinescroll()。如您所见,这是一个 CSS 函数,它接受两个参数。

第一个参数
这是应该使用其条的元素。

  • nearest(默认)- 在任一平面上都有滚动的第一个祖先。
  • root- 根元素(主体)。

第二个参数
要使用的轴。

  • block(默认)- 块轴根据书写模式而变化,但在英语中是垂直的(上下)。
  • inline- 内联轴再次根据书写模式而变化,但在英语中是水平的(左和右)。
  • 垂直 - 始终垂直(上下)。
  • 水平 - 始终水平(左和右)。
.fade-element {
  animation: fade-animation-name linear;
  animation-timeline: scroll(block root);
}
Enter fullscreen mode Exit fullscreen mode

默认情况下,滚动时间轴会使用从 0% 滚动到 100% 的整个页面,但这可能并非总是您想要的。您可能希望仅在网站的前 50% 或前 100vh 部分运行动画。使用animation-range此属性可以轻松设置。

.fade-element {
  animation: fade-animation-name linear;
  animation-timeline: scroll(block root);
  animation-range: 20vh 80vh;
}
Enter fullscreen mode Exit fullscreen mode

animation-range属性确实会根据您使用的时间线类型而略有变化,但使用滚动时,它很简单,就是开始滚动位置和结束滚动位置,默认值为0% 100%

查看进度时间表

视图时间轴基于组件及其与视口的关系。此类型的时间轴view()只有一个参数,即要使用的轴。

.fade-element {
  animation: fade-animation-name linear;
  /* this could be block | inline | vertical | horizontal */
  animation-timeline: scroll(block); 
}
Enter fullscreen mode Exit fullscreen mode

正如我之前提到的,这里animation-range的属性也发生了变化,因为现在我们有 6 个不同的范围可以使用,分别是coverentryexit。通过这些,您可以根据元素所在的范围在其上运行不同的动画。entry-crossingexit-crossingcontain

覆盖
此范围从元素首次接触屏幕底部时开始,到元素最后一部分退出屏幕时结束。

entry
此范围从元素首次接触屏幕底部时开始,到元素的最后一部分完全出现在屏幕上时结束。

退出
此范围从元素第一次离开屏幕时开始,到元素的最后一部分完全离开屏幕时结束。

入口交叉口
这与入口相同。

exit-crossing
这与出口相同。

包含
此范围从元素充满屏幕时开始,到元素第一次离开屏幕时结束。

@bramus有一个很棒的工具,您可以用它来帮助您直观地了解这些含义。

.fade-element {
  animation: fade-animation-name linear;
  animation-timeline: scroll(block); 
  animation-range: entry;
}
Enter fullscreen mode Exit fullscreen mode

时间轴View()引入了最后一个 CSS 属性,称为view-timeline-inset。此属性用于更改页面起点和终点的位置。它根据轴的不同,采用宽度或高度的百分比,可以是正数或负数。

.fade-element {
  animation: fade-animation-name linear;
  animation-timeline: scroll(block); 
  animation-range: entry;
  view-timeline-inset: 10%;
}
Enter fullscreen mode Exit fullscreen mode

演示

文章开头有一个小演示,只是为了激发你的兴趣,如果你想查看那个代码,这里是沙盒,但这里还有另外几个演示来展示什么是可能的。

滚动动画

在这个演示中,我有一个 100vh 的固定标题,向下滚动时会播放动画,显示其背后的内容。我还必须在滚动时移动主要内容,以确保其显示为静态。

这是一个 gif,以防您阅读本文时它还没有到达您的浏览器。

后退电梯动画

退出/进入动画

在这里,我夸大了元素的退出和进入,使它们看起来像是弹入(弹跳效果是通过新的CSS 线性缓和函数实现的)并缩小。

再次,这里是一张备用 gif,以防万一。

动画中的回退反弹

结束

哇,CSS 真的进步神速!好像有太多东西需要跟上,不过我倒不介意。你希望 CSS 新增哪些功能?

非常感谢你的阅读。如果你想在 Dev 之外联系我,可以点击我的TwitterLinkedIn来打个招呼😊。

文章来源:https://dev.to/link2twenty/future-of-css-scroll-animations-52ia
PREV
React:媒体查询的自定义钩子📱💻
NEXT
CSS 的未来:Popover API