viewtimeline 的 inset 并不直接控制“进出视口”触发时机,而是定义逻辑视口边界:如 inset: 100px 使上下边界各向内收缩 100px,动画 0%→100% 对应元素顶部进入/底部离开该收缩区域。

ViewTimeline 的 inset 是什么,它真能控制“进出视口”的偏移?
不能。这是最常被误解的一点:inset 并不直接控制“元素进入/离开视口”的触发时机,它只定义 ViewTimeline 的时间范围边界——即把视口的上下(或左右)边缘向内收缩多少,形成一个“逻辑视口”。动画的起止时间仍由元素与这个收缩后区域的相交关系决定。
比如 inset: 100px 表示:顶部边界下移 100px、底部边界上移 100px,中间这块区域才是 timeline 的“满刻度区间”(0% → 100%)。元素的 start 事件发生在其**顶部进入该收缩区域顶部**时,end 事件发生在其**底部离开该收缩区域底部**时。
怎么写合法的 inset 值?哪些单位和语法有效?
inset 是 ViewTimeline 的 CSS descriptor,只能在 @view-timeline 规则里声明,且必须是单个长度值(不允许百分比、calc 或负数)。
-
inset: 50px✅ 合法,上下各缩进 50px -
inset: 1rem✅ 合法,支持 rem、em、vh 等绝对/相对单位 -
inset: 10%❌ 无效,百分比不被支持 -
inset: calc(100px + 1rem)❌ 无效,不支持 calc() -
inset: -20px❌ 无效,负值会令 timeline 失效(浏览器忽略整个规则)
注意:它只接受一个值,不是 inset-top 或四值语法;多方向偏移需靠 view-timeline-name 配合不同方向的 scroll-timeline 模拟,但那是另一套机制。
为什么加了 inset 动画却没变化?常见失效原因
加了 inset 却没看到触发偏移,大概率是下面几个问题之一:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 元素未设置
view-timeline-name,或名称与@view-timeline中的不匹配 -
inset值过大,导致收缩后的逻辑视口高度 ≤ 0(例如视口高 600px,inset: 400px→ 逻辑高度仅 -200px),timeline 直接退化为无效状态 - 动画使用的是
animation-timeline: view(),但没指定正确的view-timeline-name参数,如写成view(tl)却忘了定义@view-timeline tl { inset: 100px; } - CSS 容器查询或 transform 层级干扰了视口计算(特别是父元素有
transform时,可能破坏ViewTimeline的坐标系)
调试建议:用 getComputedTimeline() 查看 timeline 实际状态,或临时加个 outline 和 background 辅助观察逻辑视口位置。
实际效果对比:inset: 0 vs inset: 150px
假设一个固定高 200px 的卡片,在垂直滚动容器中从上往下进入视口:
/* timeline 定义 */
@view-timeline card-tl {
source: selector(#my-card);
inset: 150px;
}
那么它的动画时间线分布会变成:
-
inset: 0:动画从卡片顶部触达视口顶部(0%)开始,到底部离开视口底部(100%)结束 -
inset: 150px:动画从卡片顶部触达视口向下 150px 处(即“提前触发”)开始;到卡片底部离开视口向上 150px 处(即“延迟结束”)才结束 —— 整体动画窗口被拉长,且起点更早、终点更晚
真正影响“感知偏移”的,是这个逻辑窗口的移动,而不是某个开关式触发点。如果你要实现“元素还剩 200px 才到视口就启动动画”,inset: 200px 就是直接解法;但要注意,这会让动画总时长远超元素实际在视口内的停留时间。
复杂点在于:这个偏移对不同滚动方向(水平滚动)、不同容器尺寸、以及元素自身尺寸都敏感,必须结合具体布局实测 —— 没有通用 magic number。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










