animation-range 是唯一能精确控制滚动驱动动画生效区间的属性,它通过 length-percentage(如20%)或 timeline-range-name(如entry、exit)定义起止位置,需配合 animation-timeline: view() 或 scroll() 使用,且 entry/exit 因锚定边界更稳定常用。

animation-range 是唯一能精确控制滚动驱动动画“哪一段滚动距离生效”的属性,不设它,动画默认跑满整个视口或滚动容器范围——多数时候这并不符合设计意图。
animation-range 值的含义和常见写法
它本质是 animation-range-start 和 animation-range-end 的简写,接受两类值:length-percentage(如 20%、100px)和 timeline-range-name(如 entry、cover、exit)。两者可混用,但顺序固定:第一个值总是 start,第二个是 end。
常见组合及实际效果:
-
entry 0%:元素**第一个像素刚进入视口顶部**时,动画进度为 0% -
cover 50%:元素**垂直方向覆盖视口 50% 高度**时,动画进度为 100% -
entry 20% exit 80%:动画从元素进入视口 20% 时开始,到它即将离开(还剩 20% 在视口内)时结束 -
cover 0% cover 100%:动画在元素从“刚覆盖视口 0%”(即刚露头)到“完全覆盖视口 100%”(整块填满)之间运行
为什么 entry/exit 比 cover/contain 更常用
cover 和 contain 描述的是元素在视口中的“填充比例”,但它们依赖元素自身尺寸与视口尺寸的比值,容易因响应式布局变化而漂移;entry 和 exit 则锚定在**元素边界与视口边界的交点**,语义清晰、行为稳定。
典型误用场景:
- 用
cover 0%试图替代entry 0%—— 实际上cover 0%可能根本不会触发(元素高度远小于视口时,永远达不到“覆盖 0%”) - 写成
exit 0%以为是“刚要离开就结束”,结果是“完全离开后才开始动画”(因为exit的 0% 对应完全离开时刻,100% 反而是刚接触视口底部) - 在
scroll()时间线中错误使用entry—— 它只对view()有效;scroll()时间线必须用length-percentage或scroll-timeline-range(已废弃)
animation-range 与 animation-timeline 的配合要点
它必须和 animation-timeline: view() 或 animation-timeline: scroll(...) 同时存在才起作用。单独写 animation-range 不会触发任何动画。
关键约束条件:
- 若用
view(),元素必须是普通流内元素(不能是position: fixed或transform后脱离文档流的),否则浏览器无法准确计算其视口可见性 - 若用
scroll(root y),animation-range的length-percentage值是相对于**滚动容器总滚动高度**的百分比,不是视口高度 -
entry-crossing和exit-crossing目前仅 Chromium 120+ 支持,Firefox 和 Safari 尚未实现,生产环境慎用
调试 animation-range 触发时机的小技巧
浏览器 DevTools 尚未原生支持可视化 animation-range 区间,但可通过以下方式快速验证:
- 在
@keyframes中临时加入outline: 2px solid red和opacity: 0.5,肉眼观察动画何时亮起/消失 - 把
animation-range改成极窄区间(如entry 49% entry 51%),确认是否真在“一半进入”时闪一下 - 用
console.log配合IntersectionObserver打印同一元素的intersectionRatio,对比cover X%是否与之数值一致
最易被忽略的一点:当元素有 margin-top 或父容器有 padding-top 时,entry 0% 的触发位置会向上偏移——这不是 bug,是规范定义的“元素盒模型边界”参与计算的结果,需在设计阶段就纳入考量。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











