在网页开发中,我们经常希望某些内容在用户滚动到它们时才播放动画,而不是打开页面就全部显示完毕。借助CSS过渡与IntersectionObserver,可以很低成本地实现这种滚动触发的动态变换。

核心思路
基本思路是:先把元素设为初始的隐藏或偏移状态,当浏览器观察到该元素进入视口时,给它加上一个类,这个类对应最终的可见样式,CSS过渡就会自动完成动画。
1. 定义CSS状态
我们使用opacity和transform来做渐显加位移的效果,代码如下:
/* 初始状态:透明且向下偏移20px */
.fade-box {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
/* 可见状态:完全显示且回到原位置 */
.fade-box.show {
opacity: 1;
transform: translateY(0);
}
2. 使用IntersectionObserver监听
IntersectionObserver能高效判断元素是否进入视口,不需要频繁计算滚动位置。下面是一段完整的JS示例:
// 选择所有需要动画的元素
const boxes = document.querySelectorAll('.fade-box');
// 创建观察器
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
// 如果进入视口
if (entry.isIntersecting) {
entry.target.classList.add('show');
// 动画只播放一次可取消观察
observer.unobserve(entry.target);
}
});
}, {
threshold: 0.2 // 露出20%时触发
});
// 开始观察每个元素
boxes.forEach(box => observer.observe(box));
3. HTML结构示例
页面里只需要给目标元素加上对应类名:
<div class="fade-box">我是滚动到可见区域才出现的模块</div> <div class="fade-box">另一个延迟出现的模块</div>
支持的变换类型
除了渐显和位移,还可以组合多种变换。常见类型如下:
| 效果 | CSS属性 |
|---|---|
| 缩放 | transform: scale(0.8) 到 scale(1) |
| 左滑入 | transform: translateX(-40px) 到 translateX(0) |
| 旋转出现 | transform: rotate(10deg) 到 rotate(0) |
注意事项
- 若用户禁用JS,元素会一直保持隐藏,可加noscript样式兜底。
- threshold数值根据内容高度调整,避免大元素迟迟不触发。
- 移动端同样适用,IntersectionObserver在现代浏览器中支持良好。
通过上述方式,我们用很少的代码就实现了滚动到可见区域才触发的CSS动画,既保证性能也方便后期扩展其他动态效果。
CSS动画IntersectionObserver滚动触发修改时间:2026-07-30 20:03:39