view transitions api 仅适用于单页内同步 dom 更新,跨页面跳转无效;必须用 document.startviewtransition() 包裹同步操作,确保 view-transition-name 成对唯一且元素已挂载,旧元素需保持可绘制状态。

View Transitions API 不能用于跨页面跳转,只对单页内同步 DOM 更新生效;用错场景或写法,动画就直接消失——不是浏览器不支持,而是你没让它“拍到快照”。
document.startViewTransition() 必须包裹同步 DOM 操作
它不是给路由跳转加动画的钩子,而是告诉浏览器:“接下来我要改 DOM,你快拍两张照做过渡”。一旦里面塞了异步逻辑,快照就拍歪了。
- ❌ 错误:在
startViewTransition外等数据,再进回调更新 - ✅ 正确:先拿到完整 HTML 字符串或 DOM 片段,再进回调里直接赋值
innerHTML或调用replaceChildren() - ⚠️ 注意:目标容器(比如
article)必须已挂载在 document 中,不能是刚document.createElement('div')出来还没append的 - ⚠️ 如果用框架(Vue/React),得确保你操作的是真实 DOM 节点,或用
nextTick/forceUpdate触发完渲染再进过渡
view-transition-name 必须成对、稳定、唯一
过渡是否触发,90% 看这个属性配对成功没。它不是 class,不是 id,是独立 CSS 属性,靠字符串精确匹配。
- 旧元素和新元素都得有
style="view-transition-name: title",且值完全一致(大小写敏感、不能带空格) - 不能动态生成,比如
view-transition-name: item-${id}但前后id不一致 → 匹配失败,无动画 - 别乱给非目标元素加该属性,否则它们也会被卷入过渡,干扰图层顺序
- 推荐写法:
<h1 style="view-transition-name: title">旧标题</h1>→ 新 DOM 同位置也带相同view-transition-name
::view-transition-old 和 ::view-transition-new 的样式陷阱
浏览器靠这两个伪元素控制旧/新视图的动画,但很多常见样式会让旧元素“不可见”,导致快照捕获失败,只剩新元素淡入。
- ❌ 快照前就设了
opacity: 0、visibility: hidden、display: none→ 旧元素无法参与过渡 - ✅ 过渡开始前,确保目标元素处于可绘制状态:哪怕
opacity: 0.999或用透明遮罩占位,也别动它本身 - ⚠️ 检查 DevTools 的 Layers 面板,确认过渡元素进了独立合成层(加
will-change: transform可辅助) - 默认动画是淡入淡出,自定义时注意时长统一:
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.4s; }
多页应用(MPA)中根本用不了 View Transitions
点击 <a href="/about"></a> 跳转时,当前文档卸载、新文档加载,startViewTransition() 在旧上下文里调用,新页面压根没它的执行环境。
- ❌ 不要尝试在
click事件里对location.href或a标签加过渡 - ✅ 若必须保留 MPA 架构,只能退回到
navigation API+document.visibilityState+ 自定义 CSS 过渡组合方案 - ✅ 更现实的路径是改用 SPA 路由(
history.pushState+ 手动更新 DOM),再套startViewTransition - ⚠️ 即使浏览器支持该 API,跨页场景下它也永远返回
undefined或静默失效,不会报错
最容易被忽略的一点:过渡效果是否出现,不取决于你写了多少 CSS 动画,而取决于“旧 DOM 是否还活着、新 DOM 是否已就位、view-transition-name 是否严格配对”——三者缺一不可。调试时优先检查 Layers 面板和元素 computed styles,而不是反复改 @keyframes。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











