设置滚动关联动画
在元素进入视口时触发 CSS 动画
设置滚动关联动画 是 CoddyKit 上的免费 HTML Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 HTML Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 HTML Academy 课程共包含 4 节课。
目标
滚动联动动画会根据元素的可见性播放、暂停或反向播放。示例包括:某个区块滚动进入视口时主视觉区淡入、元素可见时数字递增,以及与滚动位置关联的视差效果。IntersectionObserver 触发动画;CSS 或 Web 动画 API 执行动画。
基于触发的动画
最简单的模式是:元素进入视口时,使用 add 添加一个包含动画的 CSS 类。在观察器回调中使用 entry.target.classList.add("in-view");该类定义 animation: fade-in 600ms forwards。
.fade-up { opacity: 0; transform: translateY(20px); }
.fade-up.in-view {
animation: fadeUp 600ms cubic-bezier(.2,.8,.2,1) forwards;
}
@keyframes fadeUp {
to { opacity: 1; transform: none; }
}观察器设置
创建一个共享的 observer,使用 observe 观察每个带有触发类的元素,相交时使用 add 添加“进入视图”类,使用 unobserve 避免再次触发。对于单次动画,这些操作就足够了;如果希望元素再次进入视口时重复播放,则不要使用 unobserve,并在元素离开时移除该类。
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
entry.target.classList.add("in-view");
observer.unobserve(entry.target);
}
}
}, { threshold: 0.2 });
document.querySelectorAll(".fade-up").forEach((el) => observer.observe(el));交错效果
要让列表逐项显示,可以通过 CSS 自定义属性为每一项应用不同的延迟:在每一项上设置 style="--delay: ${i * 100}ms";动画读取 animation-delay: var(--delay)。列表进入视口时,各项会像级联一样依次播放。
更早触发的阈值
threshold: 0.2 会在元素有 20% 可见时触发——这通常是播放“进入视图”动画的好时机。threshold: 0 触发得太早(只要有一个像素可见),效果会显得突兀;threshold: 1 触发得太晚(完全可见后),感觉会有延迟。
滚动联动与滚动触发
滚动触发动画会在发生相交时播放一次(上文已介绍)。滚动联动动画的进度会与滚动位置同步推进。现代做法是使用 CSS 滚动驱动动画(animation-timeline: scroll()),而 IntersectionObserver 仍适合用于检测进入或离开触发区域。
避免布局抖动
请动画化 GPU 可以低成本变换的属性:transform 和 opacity。避免动画化 top、left、width、height——它们会在每一帧触发布局,导致滚动联动动画在中端设备上出现卡顿。
尊重减少动态效果设置
将动画声明放在 @media (prefers-reduced-motion: no-preference) 中,这样请求减少动态效果的用户(例如患有前庭障碍或对动态效果敏感的用户)可以看到没有移动效果的静态最终状态。减少动态效果时,装饰性动画应完全禁用。
.fade-up { opacity: 1; transform: none; }
@media (prefers-reduced-motion: no-preference) {
.fade-up { opacity: 0; transform: translateY(20px); }
.fade-up.in-view { animation: fadeUp 600ms forwards; }
}性能模式
使用一个共享的 observer,而不是为每个元素创建一个。单次动画触发后使用 unobserve。谨慎使用 will-change——只应用于当前正在播放动画的元素,并在动画结束时移除。通过性能面板留意丢帧情况。
双向动画
如果动画应在元素离开视口时反向播放,请不要使用 unobserve。在回调中,根据 isIntersecting 切换类:entry.target.classList.toggle("in-view", entry.isIntersecting)。元素进入视口时动画正向播放,离开时反向播放。
与 Web 动画 API 结合
对于由 JS 驱动的动画,请将 classList.add 替换为 entry.target.animate(keyframes, options)。WAAPI 会返回一个动画对象,您可以暂停、反向播放,或通过承诺链式调用;对于复杂序列,它比 CSS 更灵活。
知识检查
在滚动联动动画中,为什么更推荐动画化 transform 和 opacity,而不是 top/left/width/height?
总结
滚动联动动画会将 IntersectionObserver 与 CSS 动画类或 WAAPI 结合使用。设置隐藏状态,在相交时使用 add 添加“进入视图”类,动画化 transform 和 opacity(而不是 top/left),尊重 prefers-reduced-motion,并通过 CSS 自定义属性设置交错延迟,实现级联显示。对于完整的滚动进度动画,可以考虑原生滚动驱动动画(animation-timeline: scroll())。
常见问题解答
「设置滚动关联动画」课时是免费的吗?
是的 — 「设置滚动关联动画」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 HTML Academy 课程的其余内容,请升级到 CoddyKit PRO。 HTML Academy 课程共包含 4 节课。
「设置滚动关联动画」这节课中我会学到什么?
在元素进入视口时触发 CSS 动画 你通过在浏览器中直接运行的动手代码来练习 HTML Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 HTML Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 HTML Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「设置滚动关联动画」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 HTML Academy 课中编写并运行代码吗?
能。每节 HTML Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。