::view-transition 不是标准伪元素,浏览器仅支持 ::view-transition-old、::view-transition-new、::view-transition-group 和 ::view-transition-image-wrapper 四类;直接使用 ::view-transition 无效且无报错,因该伪元素根本不存在,所有样式必须作用于具体角色。

::view-transition 不是标准 CSS 伪元素,目前(截至 Chrome 111–125)浏览器仅支持 ::view-transition-group、::view-transition-image-wrapper 和 ::view-transition-old/::view-transition-new 这四类伪元素——直接写 ::view-transition 会完全无效。
为什么写 ::view-transition 没反应?
这是最常见的误用起点。View Transitions API 的伪元素命名有严格约定,没有顶层的 ::view-transition。所有样式必须作用于具体角色:旧内容、新内容、分组容器或图像包装器。Chrome DevTools 的 Elements 面板里也查不到该伪元素,因为它根本不存在。
常见错误现象:
- CSS 规则写了
::view-transition { opacity: 0.5; },但毫无效果 - 控制台无报错,但动画不触发,容易误以为是 JS 初始化问题
- 开发者文档搜索“view-transition”时被 MDN 的草案标题误导
::view-transition-old 和 ::view-transition-new 怎么选?
这两个伪元素对应「同一 view-transition 名称下」的旧 DOM 快照和新 DOM 快照。关键在 document.startViewTransition() 回调中是否显式设置了 name 属性。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 必须给参与过渡的元素加
view-transition-nameCSS 属性(值不能为none),否则不会被识别为 transition target - 如果多个元素共用一个 name(如都设为
"hero"),那么::view-transition-old(hero)和::view-transition-new(hero)才能精准匹配 - 不指定 name 时,浏览器会自动生成匿名 name,此时只能用泛化的
::view-transition-old,但无法保证匹配到你想要的元素
示例:想让标题淡出+缩放,需同时定义:
.title {
view-transition-name: "title";
}
::view-transition-old("title") {
animation: fadeOutScale 0.3s;
}
::view-transition-new("title") {
animation: fadeInScale 0.3s;
}
为什么 ::view-transition-group 动画卡顿或错位?
这个伪元素包裹的是整个 transition 区域的合成层,它本身不渲染内容,只提供 transform / opacity 控制入口。性能问题往往源于两点:
- 对
::view-transition-group直接设置transform: rotate()或filter: blur(),会导致整个过渡区域强制重绘,尤其在中低端 Android 设备上掉帧明显 - 未关闭
contain: layout paint等限制性属性,使浏览器无法安全地将该 group 提升为独立合成层 - 与
will-change冲突:若目标元素已设will-change: transform,再在 group 上叠加 transform 可能触发意外交互
推荐做法是:只用 ::view-transition-group 做平移/缩放锚点偏移,把复杂动画拆给 -old/-new 元素自身处理。
兼容性与降级必须手动处理
View Transitions 目前仅 Chromium 111+ 原生支持(Chrome、Edge、Opera),Firefox 和 Safari 无实现计划,且 W3C 标准尚未冻结。这意味着:
- 不能依赖
@supports (view-transition-name: none)—— 该特性查询始终返回 false,即使浏览器支持 - 正确检测方式是
if ("startViewTransition" in document) - 所有
::view-transition-*CSS 规则必须包裹在@supports selector(::view-transition-old)中,否则旧版浏览器会整条规则丢弃(连带后面合法规则)
真正容易被忽略的点:CSS 中的 @supports selector() 是实验性语法,需开启 Chrome flag(chrome://flags/#enable-css-container-queries)才能生效——生产环境应改用 JS 动态注入 style 标签,而非依赖 CSS 特性查询。


















