document.startviewtransition() 必须包裹同步 dom 更新,否则页面切换动画不会触发;css 仅支持 ::view-transition-old(root) 和 ::view-transition-new(root) 伪元素控制过渡,且仅允许 opacity、transform 动画,并需设置 animation-fill-mode: both。

document.startViewTransition() 必须包裹同步 DOM 更新
页面切换动画不会自动出现,必须显式调用 document.startViewTransition() 并把 DOM 变更逻辑写在它的回调里。浏览器靠这个信号截取“旧快照”和“新快照”,如果更新是异步的(比如 await fetch 后再改 class),就会抛 InvalidStateError 或静默失败。
常见错误包括:
- 先发请求加载新 HTML,再插入内容 → 动画不触发
- 在 React/Vue 的状态 setter 后直接调用 startViewTransition → DOM 还没渲染,快照为空
- 用
setTimeout延迟 class 切换 → 浏览器认为过渡已过期
正确做法是:所有 DOM 修改(如替换 innerHTML、切换 document.documentElement.classList、更新 data-theme)必须在回调内同步完成。
::view-transition-old(root) 和 ::view-transition-new(root) 是唯二可用的 CSS 入口
CSS 层面只能通过这两个伪元素控制整页过渡行为,其他写法浏览器会忽略。不能写成 .theme-dark ::view-transition-new(root),也不能给自定义类加 transition——这些选择器无效。
关键细节:
- 必须用
(root),不是(html)或省略括号 - 动画只能作用于
opacity、transform(如translateX、scale),避免height、top触发 layout - 务必加
animation-fill-mode: both,否则动画结束瞬间元素会回退到初始状态
例如侧滑效果:
::view-transition-old(root) {
animation: slide-out 0.3s ease both;
}
::view-transition-new(root) {
animation: slide-in 0.3s ease both;
}
@keyframes slide-out {
to { transform: translateX(-30px); opacity: 0; }
}
@keyframes slide-in {
from { transform: translateX(30px); opacity: 0; }
}
命名过渡(view-transition-name)用于局部元素动画
如果只想让某个卡片或标题有独立动画,而不是整页切换,就得用命名过渡。给目标元素加 view-transition-name 属性(值不能是空字符串),CSS 中对应使用 ::view-transition-old(<name>)</name> 和 ::view-transition-new(<name>)</name>。
注意点:
- 同一个页面中多个元素不能共用相同 name,否则动画会冲突
- name 值区分大小写,且不能含空格或特殊字符
- 如果元素在旧/新状态中都存在,浏览器会尝试做 morph(形变);若只存在于一侧,则只播单边动画
示例(给主内容区单独设名):
<main id="content" view-transition-name="main">...</main>
对应 CSS:
::view-transition-old(main) { animation: fade-out 0.25s; }
::view-transition-new(main) { animation: fade-in 0.25s; }
快速连点时旧动画残留需手动清理
用户连续点击导航链接,可能前一个 ::view-transition-old(root) 动画还没结束,新过渡就启动了。此时旧快照图层仍挂在页面上,导致视觉重叠或卡顿。
解决方式不是靠 CSS,而是 JS 主动监听并清理:
- 用
transition.finished.then()或transition.addEventListener('finish', ...)捕获完成事件 - 在回调里移除旧的临时 class(如有)、重置动画状态
- 对命名过渡元素,可加 class 控制 visibility,避免旧影子节点遮挡新内容
最容易被忽略的是:浏览器不会自动卸载已结束的视图过渡快照,尤其在 SPA 频繁跳转场景下,残留图层可能积累数层,影响性能和交互响应。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











