发布时间:2025 年 10 月 8 日
自 2023 年推出同文档视图过渡以来,发生了很多变化。
2024 年,我们推出了跨文档视图过渡,并添加了 view-transition-class 和视图过渡类型等改进功能,同时还欢迎 Safari 加入支持视图过渡的行列。
本文简要介绍了 2025 年视图过渡功能的变化。
更好的浏览器和框架支持
同文档视图过渡即将成为“Baseline 新近可用”功能
Interop 2025 的一个重点领域是 View Transition API,具体来说是使用 document.startViewTransition(updateCallback)、view-transition-class 的同文档视图过渡、使用 view-transition-name: match-element 的自动命名以及 :active-view-transition CSS 选择器。
Firefox 计划在即将发布的 Firefox 144 版本(将于 2025 年 10 月 14 日成为稳定版)中包含这些功能。这将使这些功能成为 Baseline 新增功能。
React 核心现在支持 View Transition API
在过去一年中,React 团队一直致力于将视图过渡添加到 React 的核心。他们早在 4 月就宣布react@experimental支持,而本周在 React Conf 上,他们将对它的支持移到了 react@canary 中,这意味着设计已接近最终版本。
function Child() {
return (
<ViewTransition>
<div>Hi</div>
</ViewTransition>
);
}
function Parent() {
const [show, setShow] = useState();
if (show) {
return <Child />;
}
return null;
}
您可以查看 React 的 <ViewTransition>文档了解所有详情,也可以观看 Aurora Scharff 的这段讲座,以便很好地了解相关主题。
最近发布的功能
使用 view-transition-name: match-element 自动命名元素
Browser Support
如需将某个元素标记为视图过渡的一部分,请为其指定 view-transition-name。这对于视图过渡至关重要,因为它可以解锁在两个不同元素之间过渡等功能。每个元素在过渡的每一侧都具有相同的 view-transition-name 值,而视图过渡会为您处理相关事宜。
不过,当转换许多实际上没有变化的元素时,为元素提供唯一名称可能会很麻烦。如果您有 100 个元素在列表中移动,则必须想出 100 个唯一名称。
借助 match-element,您无需执行所有这些操作。如果将此值用作 view-transition-name 的值,浏览器将根据每个匹配元素的身份信息为每个匹配元素生成一个内部 view-transition-name。
以下演示中使用了此方法。该行中的每张卡片都会获得自动生成的 view-transition-name。
.card {
view-transition-name: match-element;
view-transition-class: card;
}
#targeted-card {
view-transition-name: targeted-card;
view-transition-class: none;
}
进入或退出的卡片会获得一个明确的名称。该名称用于在 CSS 中将特定动画附加到相应快照。所有其他卡片的快照都使用与其关联的 view-transition-class 进行样式设置。
/* Style all pseudos with the class .card */
::view-transition-group(*.card) {
animation-timing-function: var(--bounce-easing);
animation-duration: 0.5s;
}
/* Style only the targeted-card's pseudos */
::view-transition-old(targeted-card):only-child {
animation: animate-out ease-out 0.5s forwards;
}
::view-transition-new(targeted-card):only-child {
animation: animate-in ease-in 0.25s forwards;
}
开发者工具现在会显示以伪类为定位目标的规则,这些规则使用 view-transition-class
如需调试视图过渡,您可以使用开发者工具中的“动画”面板暂停所有动画。这样,您就有时间检查伪元素,而无需担心视图过渡会达到完成状态。您甚至可以手动浏览动画的时间轴,查看过渡的播放方式。
以前,在检查某个 ::view-transition-* 伪元素时,Chrome 开发者工具不会显示以伪元素为目标的规则(使用其设置的 view-transition-class)。Chrome 139 中添加了相应功能,因此这种情况已发生变化。
view-transition-group 伪元素的屏幕截图。“样式”标签页会显示影响该伪元素的规则,包括使用 view-transition-group(*.card) 选择器的规则。嵌套视图过渡组自 Chrome 140 起可用
Browser Support
当视图转换运行时,它会在伪元素树中渲染拍摄的元素。默认情况下,生成的树是“扁平”的。这意味着 DOM 中的原始层次结构会丢失,并且所有捕获的视图过渡组都将成为单个 ::view-transition 伪元素的同级元素。
这种扁平树方法足以满足许多使用情形,但在使用剪裁或 3D 转换等视觉效果时会遇到问题。这些效果需要在树中具有一定的层次结构。
借助嵌套的视图过渡组,您现在可以将 ::view-transition-group 伪元素相互嵌套。当视图过渡组嵌套时,可以在过渡期间恢复剪切等效果。
伪元素现在可继承更多动画属性
如果您在 ::view-transition-group(…) 伪元素上设置了某个 animation-* 详写属性,则包含的 ::view-transition-image-pair(…)、::view-transition-old(…) 和 ::view-transition-new(…) 也会继承该属性。这非常方便,因为它可以自动使 ::view-transition-new(…) 和 ::view-transition-old(…) 之间的淡入淡出与 ::view-transition-group(…) 保持同步。
::view-transition-group(.card) {
animation-duration: 0.5s;
}
最初,这种继承仅限于 animation-duration 和 animation-fill-mode(后来也包括 animation-delay),但现在已扩展为可继承更多动画简写属性。
支持视图过渡的浏览器现在应在其用户代理样式表中包含以下内容
:root::view-transition-image-pair(*),
:root::view-transition-old(*),
:root::view-transition-new(*) {
animation-duration: inherit;
animation-fill-mode: inherit;
animation-delay: inherit;
animation-timing-function: inherit;
animation-iteration-count: inherit;
animation-direction: inherit;
animation-play-state: inherit;
}
继承更多属性的伪元素已在 Chrome 140 中发布。
finished promise 回调的执行不再等待帧
使用 finished promise 执行回调时,Chrome 过去会等待生成一个帧,然后再执行该逻辑。当脚本尝试保留视觉上相似的状态而移动某些样式时,这可能会导致动画结束时出现闪烁。
document.startViewTransition(() => {
if (from) {
dfrom.classList.remove("shadow");
dto.appendChild(target);
} else {
dto.classList.remove("shadow");
dfrom.appendChild(target);
}
}).finished.then(() => {
if (from) {
dto.classList.add("shadow");
} else {
dfrom.classList.add("shadow");
}
from = 1 - from;
});
此时间安排方面的更改通过将视图过渡清理步骤移至生命周期完成后异步运行,从而纠正了这种情况。这样可确保在 finished 承诺的分辨率下生成的视觉帧仍保持视图过渡结构,从而避免闪烁。
此时间变化已在 Chrome 140 中提供。
即将发布的功能
今年尚未结束,因此我们还有时间推出更多功能。
Chrome 140 中已可测试范围限定的视图过渡
Browser Support
限定了范围的视图转换是 View Transition API 的一项提议的扩展功能,可让您通过在任何 HTMLElement 上调用 element.startViewTransition()(而非 document.startViewTransition())来对 DOM 的子树启动视图转换。
范围限定的过渡效果允许同时运行多个视图过渡效果(只要它们具有不同的过渡根)。指针事件仅在相应子树(您可以重新启用)上被阻止,而不是在整个文档上被阻止。此外,它们还允许在范围限定的视图过渡效果之上绘制过渡根之外的元素。
在以下演示中,您可以通过点击某个按钮来移动容器内的圆点。这可以通过文档范围的视图过渡或元素范围的视图过渡来实现,让您了解它们的行为方式有何不同。
从 Chrome 140 开始,此功能已可供测试,只需在 chrome://flags 中启用“实验性 Web 平台功能”标志即可。我们正积极征求开发者的反馈。
::view-transition 的位置将在 Chrome 142 中从 fixed 更改为 absolute
::view-transition 伪元素目前使用 position: fixed 进行定位。根据 CSS 工作组的决议,此值将更改为 position: absolute。
这种 position 值从 fixed 更改为 absolute(即将在 Chrome 142 中推出)在视觉上无法观察到,因为 ::view-transition 伪元素所处的包含块本来就是快照包含块。唯一可观测到的效果是在执行 getComputedStyle 时 position 值不同。
document.activeViewTransition 即将登陆 Chrome 142
当视图过渡开始时,系统会创建一个 ViewTransition 实例。此对象包含多个 promise 和用于跟踪过渡进度的功能,还允许进行跳过过渡或修改过渡类型等操作。
现在,Chrome 提供了一个表示此对象的 document.activeViewTransition 属性,您无需再手动跟踪此实例。如果没有正在进行的过渡,该属性的值为 null。
对于同文档视图过渡,该值会在您调用 document.startViewTransition 时设置。对于跨文档视图过渡,您可以在 pageswap 和 pagereveal 事件中访问该 ViewTransition 实例。
对 document.activeViewTransition 的支持即将在 Chrome 142 中推出。
使用 ViewTransition.waitUntil 防止视图过渡自动完成
当视图转换的所有动画都完成时,它会自动达到 finished 状态。如需阻止此自动完成操作,您很快就可以使用 ViewTranistion.waitUntil。传入 promise 时,只有在传入的 promise 也得到解决时,ViewTransition 才会达到其 finished 状态。
const t = document.startViewTransition(…);
t.waitUntil(async () => {
await fetch(…);
});
此项更改将于今年晚些时候推出,届时您将能够等待 fetch 或更轻松地实现滚动驱动的视图过渡。
后续步骤
正如您所见,自 2023 年首次发布视图过渡功能以来,我们一直在不断努力。我们期待在未来发布限定了范围的视图转换功能,并一如既往地欢迎大家提供反馈。
如果您对视图过渡有疑问,请通过社交媒体与我们联系。有关视图过渡的功能请求可以提交给 CSS WG。如果您遇到 bug,请提交 Chromium bug 以告知我们。