intersectionobserver + css 动画是最优解,因其天然规避滚动卡顿、缩放偏移、iframe隔离、overscroll异常等问题;js仅开关类名,css定义动画,配合will-change提升性能。

直接用 IntersectionObserver + CSS 动画是最稳、最轻量的降级方案,不是“退而求其次”,而是当前兼容性事实下的最优解。
为什么不能只靠 CSS.supports 检测后 fallback 到 JS 监听 scroll
scroll 事件在快速滚动时频繁触发,直接在里面读取 getBoundingClientRect() 或计算 scrollTop 容易卡顿;更关键的是,它无法准确处理以下情况:
- 页面缩放(
devicePixelRatio变化)导致视口坐标偏移 - iframe 内嵌内容或
position: fixed元素的滚动上下文隔离 - 移动端 overscroll bounce 引起的临时负值或超限值
而 IntersectionObserver 是浏览器原生的异步观察机制,天然规避这些问题,且回调中拿到的 intersectionRatio 和 boundingClientRect 已经是归一化后的稳定值。
用 IntersectionObserver 触发 CSS 动画的关键写法
核心思路是:CSS 负责定义动画(@keyframes),JS 只负责开关(添加/移除类名),不参与任何数值计算或样式设置。
- 给目标元素预设一个基础类(如
.fade-in),其@keyframes已写好起止状态 - 监听
isIntersecting === true时,动态添加.animate类来启动动画(animation-play-state: running或直接用animation简写) - 若需重播(比如滚动回退再进入),每次进入前先
el.classList.remove('animate'),再add - 务必加
will-change: transform或opacity到目标元素,防止重排抖动
示例片段:
.fade-in {
opacity: 0;
transform: translateY(20px);
animation: fadeSlide 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}
.fade-in.animate {
animation-play-state: running;
}
@keyframes fadeSlide {
to { opacity: 1; transform: translateY(0); }
}
需要连续映射滚动进度时怎么处理
IntersectionObserver 默认只给“进/出”二值信号,但你可以用它估算相对滚动位置:
- 监听容器(如
#scroller)而非单个元素,设置rootMargin: "0px" - 在回调中读取
entries[0].boundingClientRect.top和entries[0].rootBounds.height - 算出比例:
const ratio = Math.max(0, Math.min(1, (rootHeight - top) / rootHeight)) - 用
requestAnimationFrame更新自定义属性:el.style.setProperty('--scroll-ratio', ratio),再在 CSS 中用transform: scaleY(calc(1 + 0.3 * var(--scroll-ratio)))
注意:这个比例只是近似值,不能替代 scroll-timeline 的精确帧对齐,但对缩放、透明度、位移等非关键路径动画完全够用。
最容易被忽略的兼容细节
很多项目写了 fallback 却仍失效,问题往往出在三处:
-
IntersectionObserver构造时没传{ root: document.documentElement },导致在body高度不足时无法触发 - 目标元素被
contain: paint或transform隔离,使 observer 无法正确获取布局信息 - 动画类名添加后,未等待下一次重绘就试图读取
getComputedStyle(el).animationName—— 这种调试逻辑会破坏性能,也无必要
真正落地时,别试图“复刻 scroll-timeline 的所有能力”,而是明确每个动画的实际需求:是只需一次入场?还是必须随滚动线性变化?前者用 IntersectionObserver 开关即可,后者才值得引入 requestAnimationFrame + scrollTop 手动计算。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











