view-timeline必须作用于被观测元素本身,即“subject”,而非动画元素或父容器;它定义可见性触发源,需配合animation-timeline使用,且仅在有滚动行为的容器内生效。

view-timeline 必须作用于被观测的元素本身
很多人一上来就给要动画的元素加 view-timeline: --rotate-tl,结果完全没反应——因为 view-timeline 不是绑定动画的属性,而是定义“谁来触发时间线”的声明。它必须写在**那个即将进入/离开视口的元素**上,也就是“subject”。浏览器靠它感知可见性变化,才能生成 0% → 100% 的进度。
常见错误现象:animation-timeline: --rotate-tl 生效但动画不动,大概率是 view-timeline: --rotate-tl 写错了位置,比如写在父容器或动画元素的兄弟节点上。
-
view-timeline只能用在 subject 元素(即你想让它“随进入视口而动”的那个元素)或其子元素上 - subject 必须在某个有滚动行为的容器内(
overflow: auto/scroll),否则视口可见性无从判断 - 不支持伪元素(
::before/::after)作为 subject
旋转动画必须用 transform + will-change 触发硬件加速
直接对 rotate() 做动画,如果没配对 transform 和 will-change,容易卡顿甚至跳帧。CSS 滚动驱动动画全程走合成器线程,但前提是属性可被 GPU 加速。只有 transform、opacity、filter 这三类属性满足条件。
所以不能写 animation: spin 1s linear; @keyframes spin { from { rotate: 0deg; } to { rotate: 360deg; } } —— rotate 单独出现不触发硬件加速,且不是标准 CSS 属性(需写成 transform: rotate())。
立即学习“前端免费学习笔记(深入)”;
- 必须用
transform: rotate(),不能只写rotate - 建议在动画元素上加
will-change: transform,提前告知浏览器该元素将频繁变换 - 避免在
@keyframes中混用 layout 触发属性(如height、margin),否则会强制回退到主线程渲染
animation-range 控制旋转起止点,别依赖默认值
默认 animation-range: entry 0% cover 100%,意思是“从刚进视口开始,到完全覆盖视口结束”。但实际中,元素可能很高,或者你只想让它在中间 40% 区域内完成旋转,这时必须显式设置 animation-range,否则动画会过早/过晚触发,甚至只播一半就停了。
例如:一个高 80vh 的卡片,你希望它在“进入视口 20% 后开始转,转到 80% 时刚好满圈”,就得写 animation-range: entry 20% cover 80%。
-
entry指元素上边缘触达视口下边缘(即刚开始可见) -
cover指元素下边缘触达视口上边缘(即完全可见) - 数值单位只能是
%,不能是px或rem - 如果设成
entry 0% exit 100%,动画会在元素完全离开视口时才播完,容易误判
Firefox 159+ 和 Chrome 115+ 才真正可用,别在旧版硬扛
截至 2026 年 11 月,view-timeline 在 Firefox 159(2026 年 10 月发布)和 Chrome 115+ 中已稳定支持。但 Safari 官方仍未启用,Edge 虽跟进了 Chromium 内核,仍需确认是否开启实验性 flag(edge://flags/#enable-scroll-driven-animations)。
这意味着:如果你现在就上线 view-timeline 旋转效果,Safari 用户看到的是静止元素,且不会 fallback 到 JS 方案——因为 CSS 层面根本没有降级机制。
- 必须搭配
@supports (animation-timeline: view())做特性检测 - 降级方案只能靠 JS 补充(例如用 IntersectionObserver 监听 +
element.animate()) - 不要用
scroll-timeline替代view-timeline来“凑合”,二者语义和触发逻辑完全不同
最易被忽略的一点:view-timeline 的进度计算依赖滚动容器的 block-size(即高度),如果容器高度为 auto 且子内容未撑开,时间线根本无法生成——动画永远不会启动。务必确保滚动上下文真实存在、可测量。


















