发布时间:2025 年 12 月 12 日
2023 年,我们推出了滚动驱动的动画,让您可以通过滚动来前进(或后退)动画。借助滚动条驱动的动画,动画进度会随着滚动从 0% 推进到 100%。如果您停止滚动,动画会暂停;如果您向上滚动,动画会反向播放。
基于滚动的动画的下一个篇章将于 2026 年到来,届时 Chrome 145 将推出滚动触发的动画。这些是基于时间的动画,会在滚动到特定偏移量时触发。
告别此类效果的 IntersectionObserver,因为您现在可以在 CSS 中以声明方式实现此类效果。
时间轴触发器、动画触发器和操作
触发动画
如需在 CSS 中设置滚动触发的动画,请先创建一个附加到元素的常规 CSS 动画:
animation: unclip 0.35s ease-in-out both;
此动画使用 DocumentTimeline 作为驱动程序,运行时间为 0.35 秒。动画会在网页加载后自动触发。如需更改触发器,请使用新的 animation-trigger CSS 属性:
animation-trigger: --t play-forwards play-backwards;
在此示例中,动画设置为由触发器 --t 触发。当该触发器被激活时,系统会在动画上调用 play-forwards 操作;当该触发器被停用时,系统会调用 play-backwards 操作。
规范包含操作的完整列表。
创建触发器
但这个--t触发因素是什么?这是一个名为 --t 的触发器。对于滚动触发的动画,它是一种“时间轴触发器”,使用滚动进度时间轴或查看进度时间轴作为其来源。
如需定义时间轴触发器,请使用 timeline-trigger 属性(或其关联的长属性)。例如,如需创建以查看时间轴为来源的名为 --t 的触发器,请使用以下代码:
timeline-trigger-name: --t;
timeline-trigger-source: view();
此创建的触发器 --t 会根据与匹配元素关联的视图时间轴来激活和停用。由于视图时间轴的默认范围是cover 范围,因此当位于该范围内或范围外时,触发器也会相应地激活和停用。
调整触发器的范围
如需调整触发器应处于有效或无效状态的位置,请在触发器上指定激活范围和有效范围。在以下示例中,激活范围设置为 entry 100% exit 0%,这意味着当拍摄对象位于该范围内时,触发器将激活。
timeline-trigger:
--t
view()
entry 100% exit 0%
;
由于上述代码段中未指定有效范围,因此激活范围也用作有效范围。当超出该有效范围时,触发器会被停用。
当与已定义的 animation-trigger 结合使用时,在视觉上,当主题完全进入滚动端口时,动画会向前播放;当主题即将离开滚动端口时,动画会向后播放。
entry 100% exit 0%。该演示还显示了调试线,用于指示范围的开始和结束位置。
可以有不同的激活范围和有效范围。例如:
timeline-trigger:
--t
view()
entry 100% exit 0% / entry 0% exit 100%
;
在此示例中,当主题位于 entry 100% exit 0% 范围内时,触发器会激活。触发器会保持有效状态,直到它离开 entry 0% exit 100% 范围。
从视觉上看,这会导致动画在主题进入滚动端口时向前播放,并且与之前不同的是,动画将一直处于活动状态,直到主题完全离开滚动端口。
entry 100% exit 0% / entry 0% exit 100%。该演示还显示了调试行,以指示范围的开始和结束位置。活动范围包含滚动视口,因此其调试线不可见。
限制触发器的范围
触发器是全局可见的,这意味着声明具有特定名称的触发器的最后一个匹配项“胜出”。如需限制触发器的可见性,请使用 trigger-scope 属性。这与 anchor-scope 的使用方式类似。
trigger-scope: --t; /* List of dashed idents, or `all` */
如果您有一条声明触发器的 CSS 规则,并且该规则与多个元素匹配,则需要使用 trigger-scope。
演示
在以下演示中,表单分布在多个全高部分中。当表单的每个部分进入视图时,系统会使用滚动触发的动画将其显示出来。离开滚动视口时,它会以动画形式淡出。
此动画的滚动触发逻辑如下:
@keyframes card {
from { translate: 0 -50% 0; }
}
@keyframes card-contents {
from { opacity: 0; height: 0px; }
to { opacity: 1; height: auto; }
}
.card {
overflow-y: clip; /* Hide any overflow in the y-axis */
timeline-trigger:
--t
view()
contain 15% contain 85% / entry 100% exit 0%
;
trigger-scope: --t;
animation: unclip var(--duration) ease-in-out both;
animation-trigger: --t play-forwards play-backwards;
}
.card > * {
interpolate-size: allow-keywords; /* To animate to `height: auto` */
animation: card-contents var(--duration) ease-in-out both;
animation-trigger: --t play-forwards play-backwards;
}
分解后,代码如下所示:
timeline-trigger的名称为--t,其来源设置为跟踪匹配元素的视图时间轴。- 触发器的激活范围为
contain 15% contain 85%。当拍摄对象位于该范围内时,触发器会变为有效状态。 - 触发器激活后,只要正文在
entry 100% exit 0%的有效范围内,触发器就会保持有效状态。 unclip动画已附加到相应元素。- 动画设置为使用
--t作为其触发源。当触发器变为有效状态时,动画开始正向播放。 - 当触发器停用(即拍摄对象离开有效范围)时,动画会反向播放。
- 卡片的内容也会使用相同的触发器
--t淡入和淡出。
该示例包含一个后备方案,使用 IntersectionObserver 来处理不支持 timeline-trigger 的浏览器。
更多演示
如果您对滚动触发的动画非常感兴趣,不妨查看以下演示:
反馈
我们很想听取您的反馈,以便继续改进此功能。您可以在社交媒体上与我们联系,也可以向 CSS 工作组提交问题来提供反馈。
如果您遇到 bug,请提交 Chromium bug 以告知我们。已知 bug 列表:请参阅 Chromium Bug Tracker。