view transitions api 仅在单页内同步 dom 更新时生效,需用 document.startviewtransition() 包裹立即执行的 dom 操作,确保元素已挂载、命名一致且样式不破坏快照可绘制性。

View Transitions API 能实现真正平滑的页面切换,但必须用对地方——它只在单页内同步 DOM 更新时生效,不是给 a href 或 location.href 加动画的“万能开关”。
document.startViewTransition() 必须包裹同步 DOM 更新
浏览器靠拍“旧快照”和“新快照”来生成过渡,这要求所有 DOM 变更必须在回调里**立刻完成**,不能异步延迟。
- ✅ 正确写法:
document.startViewTransition(() => { main.replaceChildren(newContent); }) - ❌ 错误写法:
document.startViewTransition(() => { fetch('/page').then(html => main.innerHTML = html); })——fetch是异步的,快照早已拍完 - ⚠️ React/Vue 用户注意:不要只调
router.push()或改状态,得确保视图更新已同步落地。React 可用flushSync包裹;Vue 用nextTick后再触发 - ⚠️ 目标容器(如
<main></main>)必须已在文档中挂载,不能是刚createElement出来还没append的节点
::view-transition-old(root) 和 ::view-transition-new(root) 的样式陷阱
这两个伪元素控制整页过渡,默认是淡入淡出,但自定义时稍不注意就会出现空白帧或动画丢失。
- ❌ 禁止在快照前隐藏旧内容:
display: none、visibility: hidden、opacity: 0都会让旧快照为空 - ✅ 安全替代:
opacity: 0.001占位,或用backdrop-filter: blur(1px)模拟遮罩 - ⚠️ 动画时长必须一致:
::view-transition-old(root)和::view-transition-new(root)的animation-duration不同,会导致旧层早退、新层晚到,中间闪白 - ? 调试建议:打开 Chrome DevTools → Layers 面板,确认带 “View Transition” 标签的合成层是否出现
view-transition-name 配对失败是最常见的“没动画”原因
命名过渡靠字符串精确匹配,大小写、空格、引号、值稳定性缺一不可,90% 的失效都卡在这一步。
- ✅ 正确示例:
<img src="hero.jpg" style="max-width:90%">→ 新 DOM 中同位置也必须有完全相同的style="view-transition-name: hero" - ❌ 错误示例:
view-transition-name: item-${id},但前后id不同;或一个写"hero",另一个写"Hero" - ⚠️ 同一快照内不能重复使用同一名称:两个
div都设view-transition-name: title,浏览器无法区分谁对应谁 - ⚠️ 元素必须已挂载:动态创建后立即加
view-transition-name,但还没append到 document,就不会被拍进快照
真正难的不是写几行 CSS 动画,而是让 DOM 更新满足浏览器拍快照的所有前提——同步、已挂载、命名稳定、样式不破坏可绘制性。漏掉任意一点,动画就静默失效,连报错都不会有。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











