View Transitions API 动画仅对单页内同步 DOM 更新生效,需用 document.startViewTransition() 包裹真实 DOM 替换操作,确保 view-transition-name 完全一致且元素已挂载、可见,避免异步操作与隐藏样式导致快照失败。

View Transitions API 不能直接给 a href 或 location.href 加动画——它只对单页内同步 DOM 更新生效。路由切换要平滑,关键不是“怎么跳”,而是“怎么换内容”。
document.startViewTransition() 必须包裹 DOM 更新,不是导航指令
很多人写 document.startViewTransition(() => { router.push('/detail') }),结果没动画。因为 router.push 只是发导航信号,不改 DOM;浏览器拍不到“旧快照”,自然过渡失败。
- ✅ 正确做法:先拿到新内容(HTML 字符串、DOM 片段或组件渲染结果),再在回调里直接操作真实 DOM,比如
main.replaceChildren(newContent)或app.innerHTML = html - ⚠️ 框架用户注意:Vue 要等
nextTick后再进过渡;React 推荐用flushSync包裹更新,确保 DOM 已同步 - ❌ 避免在回调里做
await fetch()、setTimeout或事件监听,快照会在回调开始时立刻拍摄,异步操作会导致 DOM 还没变就结束过渡
view-transition-name 配对失败是“没动画”的最常见原因
90% 的静默失败,都出在 view-transition-name 字符串没对上。它不是 class,不支持动态拼接,大小写和空格都必须完全一致。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 旧元素必须有
style="view-transition-name: hero",新元素同位置也得有完全相同的值(包括引号、空格、大小写) - 不能写成
view-transition-name: item-${id}且前后id不同——匹配失败,浏览器直接跳过该元素的过渡 - 元素必须已挂载:刚
createElement但还没append到 document 的节点,不会被拍进快照 - 调试建议:打开 DevTools → Layers 面板,搜索 “View Transition”,确认目标元素是否生成了独立合成层;没有就说明配对失败或元素不可见
::view-transition-old 和 ::view-transition-new 的样式陷阱
浏览器把旧/新视图分别渲染为两个合成层,但很多 CSS 会让旧层“不可绘制”,导致快照为空,只剩新内容淡入——看起来像没动画。
立即学习“前端免费学习笔记(深入)”;
- ❌ 绝对禁止在快照前设
display: none、visibility: hidden或opacity: 0;这些会让旧元素无法参与过渡 - ✅ 替代方案:用
opacity: 0.001占位,或加半透背景 +backdrop-filter模拟遮罩效果 - ⚠️ 自定义动画时,务必统一
animation-duration:若::view-transition-old(root)动画 0.3s 结束,而::view-transition-new(root)是 0.5s,中间会出现空白帧 - 默认有 fade 效果,想覆盖它就得显式重置
opacity和transform,否则旧层提前消失、新层延迟入场
真正卡住人的地方,往往不是怎么写动画,而是 DOM 是否已挂载、view-transition-name 是否稳定、旧元素是否还“看得见”。这些条件缺一不可,漏一个,过渡就静默失效。


















