必须调用 document.startviewtransition() 才会生成 ::view-transition-old(root) 等伪元素;未触发过渡、dom 更新未被包裹、浏览器不支持(如 safari)或选择器写法错误(如加前缀)均导致无效。

为什么直接写 ::view-transition-old(root) 没反应?
浏览器只在调用 document.startViewTransition() 后才生成这两个伪元素,不是写了 CSS 就自动生效。没触发过渡、没包裹 DOM 更新、或者用了不支持的浏览器(如 Safari 当前仍不支持),都会导致伪元素根本不出现在 computed styles 里。
常见错误包括:
• 在未调用 startViewTransition() 的场景下单独测试该伪类
• 把 ::view-transition-old(root) 写成 .theme-dark ::view-transition-old(root) —— 浏览器会忽略所有带前缀的组合选择器
• 用 Firefox 或旧版 Chrome(
::view-transition-old(root) 必须配合 ::view-transition-new(root) 使用
这两个伪元素是成对出现的“快照层”:旧视图负责淡出/移出,新视图负责淡入/移入。单独定义其中一个,动画会卡在中间状态或完全不播。
实操建议:
• 动画时长必须一致(比如都设 0.3s),否则会出现错帧或残留
• 两个伪元素都加 animation-fill-mode: both,防止动画结束瞬间回退到初始值
• 不要用 height、top、left 等触发布局计算的属性,优先选 opacity 和 transform
示例:
::view-transition-old(root) {<br> animation: slide-out 0.3s ease-out both;<br>}<br>::view-transition-new(root) {<br> animation: slide-in 0.3s ease-out both;<br>}<br>@keyframes slide-out {<br> from { opacity: 1; transform: translateX(0); }<br> to { opacity: 0; transform: translateX(-30px); }<br>}<br>@keyframes slide-in {<br> from { opacity: 0; transform: translateX(30px); }<br> to { opacity: 1; transform: translateX(0); }<br>}
命名视图(view-transition-name)比 root 更可控
整页过渡用 root 简单,但一旦页面里有多个动态区域(比如侧边栏 + 主内容区),root 会把整个 HTML 当作一个块来拍快照,导致局部更新也全屏动。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
更稳妥的做法是给关键容器加 view-transition-name:
• 给主内容区加 style="view-transition-name: main"
• 对应写 ::view-transition-old(main) 和 ::view-transition-new(main)
• 这样只有该元素参与过渡,其他部分(导航栏、footer)保持静止
注意:
• 同一时刻只能有一个元素拥有相同 view-transition-name 值,重复会导致行为不可预测
• 名称不能含空格或特殊字符,推荐用小写连字符(如 sidebar)
• 如果要过渡多个区域,需为每个区域分配唯一名称并分别定义伪元素
动画结束后 DOM 状态可能还没就位
::view-transition-old(root) 动画播完时,旧 DOM 已被移除或替换,但浏览器尚未完成重排重绘。此时若 JS 立即操作新节点(比如 focus() 或读取 offsetHeight),可能拿到错误尺寸或报错。
正确时机:
• 监听 transition.finished Promise,而不是靠 CSS animationend
• 或用 requestAnimationFrame 延迟到下一帧再操作新 DOM
• 框架用户(React/Vue)务必确认:DOM 更新已同步完成,且不在异步渲染周期中
容易被忽略的是:即使动画看起来结束了,document.body.innerHTML = ... 这类操作后的节点仍可能处于“半挂载”状态,尤其在快速连点切换时 —— 这时候手动清理旧过渡类、延迟焦点逻辑,比硬等动画时间更可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










