写了五年滚动动画,每次入场都要写一整块 IntersectionObserver——今天 Chrome 145 用一个属性把这个彻底原生化了

写了五年滚动动画,每次入场都要写一整块 IntersectionObserver——今天 Chrome 145 用一个属性把这个彻底原生化了。

做过滚动reveal效果的前端都知道这个流程:写一个 IntersectionObserver,监听 N 个元素,每次回调里给元素加上 class,然后在 CSS 里写 transition。这套写法在项目里一躺就是几十行,调试的时候要同时翻 JS 和 CSS,还经常遇到 observer.disconnect() 漏写导致内存泄漏。

现在可以全删了。

Chrome 145 引入的 animation-trigger 属性,让浏览器自己在滚动时触发 CSS 动画的播放,不再需要一行 JavaScript。

具体怎么写?

旧写法(IntersectionObserver):

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.1 });
document.querySelectorAll('.reveal').forEach((el) => observer.observe(el));

CSS transition:

.reveal { opacity: 0; transform: translateY(40px); transition: all 0.6s ease-out; }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

新写法(animation-trigger):

@keyframes reveal {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}
.reveal {
  animation: reveal 0.6s ease-out both;
  animation-trigger: --fade-in play-forwards;
  timeline-trigger-name: --fade-in;
  timeline-trigger-source: view();
}

纯 CSS,零 JS。

animation-trigger 接收一个命名触发器,绑定 timeline-trigger-name 定义的名称,play-forwards 意思是进入触发范围时正向播放动画。和 IntersectionObserver 的区别在于:IntersectionObserver 只告诉你「元素过了阈值」,动画播放由你决定;animation-trigger 是浏览器在适当的时机自动触发播放,不需要任何 JS 介入。

还有一个关键区别。Scroll-driven animation(比如 animation-timeline: view())的进度条是和滚动位置强绑定的——滚动停止,动画就停在原地。animation-trigger 是「一次性触发」,触发了就开始按自己 duration 走,跟滚动是否继续无关。

play-forwards 之外还有几个动作:play-backwards(退出范围时反向播放)、pause(暂停)、reset(归零并暂停)、replay(归零重新播放)、play-once(触发一次后不再响应)。

浏览器支持情况:Chrome 145+ 已支持,Safari 和 Firefox 尚未实现,spec 目前还是 Editor’s Draft,正式标准之前语法可能还会有调整。生产环境使用建议加一个 @supports 降级:

@supports (animation-trigger: --x) {
  .reveal { /* animation-trigger 版本 */ }
}

下一步怎么用?

  1. 把现有的 IntersectionObserver 滚动动画换成 animation-trigger,实测效果——Chrome 145+ 直接可用
  2. 配 trigger-scope 做作用域隔离,避免同名触发器冲突
  3. 记得加 prefers-reduced-motion 媒体查询,给减少动效需求的用户提供降级

这个属性的落地标志着 CSS 在交互控制上又往前走了一步:以前「进入视口触发」是 JS 的专属能力,现在浏览器把它原生接走了。

评论区

0 条评论

登录后可评论。

小鹿·界面实验室 753 阅读