视图过渡的新变化(2025 年更新)

发布时间:2025 年 10 月 8 日

自 2023 年推出同文档视图过渡以来,发生了很多变化。

2024 年,我们推出了跨文档视图过渡,并添加了 view-transition-class视图过渡类型等改进功能,同时还欢迎 Safari 加入支持视图过渡的行列。

本文简要介绍了 2025 年视图过渡功能的变化。

更好的浏览器和框架支持

同文档视图过渡即将成为“Baseline 新近可用”功能

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox Technology Preview: supported.
  • Safari: 18.

Source

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

  • Chrome: 137.
  • Edge: 137.
  • Firefox Technology Preview: supported.
  • Safari: not supported.

如需将某个元素标记为在视图转换期间进行快照拍摄,请为其提供 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 的定位伪类的规则

如需调试视图过渡,您可以使用 DevTools 中的“动画”面板暂停所有动画。这样,您就有时间检查伪元素,而不必担心视图过渡会达到完成状态。您甚至可以手动浏览动画的时间轴,查看过渡效果的播放方式。

使用 Chrome 开发者工具调试视图过渡。

以前,在检查 ::view-transition-* 伪元素之一时,Chrome 开发者工具不会公开以其设置的 view-transition-class 为目标的伪元素规则。Chrome 139 中添加了此功能,因此情况发生了变化。

图:Chrome 开发者工具检查卡片演示中的 view-transition-group 伪元素的屏幕截图。“样式”标签页会显示影响该伪元素的规则,包括使用 view-transition-group(*.card) 选择器的规则。

嵌套视图过渡组从 Chrome 140 开始提供

Browser Support

  • Chrome: 140.
  • Edge: not supported.
  • Firefox: not supported.
  • Safari: not supported.

当视图转换运行时,它会在伪元素的树中渲染拍摄的元素。默认情况下,生成的树是“扁平”的。这意味着 DOM 中的原始层次结构会丢失,并且所有捕获的视图过渡组都将成为单个 ::view-transition 伪元素的同级元素。

这种扁平树方法足以应对许多使用情形,但在使用剪裁或 3D 转换等视觉效果时会遇到问题。这些都需要树状结构中的某种层次结构。

演示的录制视频,其中分别展示了启用和未启用嵌套视图过渡组的情况。如果使用嵌套的视图过渡组,文本内容可能会被卡片剪裁,并且文本也会随卡片一起以 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-durationanimation-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;
});
之前代码的运行情况记录,在 Chrome 139 中录制,不包含时间修复。您可以看到,当过渡完成时,方框的阴影会添加,从而产生故障。

此时间安排方面的更改通过将视图过渡清理步骤移至生命周期完成后异步运行,从而纠正了这种情况。这可确保在 finished 承诺分辨率下生成的视觉帧仍保持视图过渡结构,从而避免闪烁。

时间安排变更已在 Chrome 140 中提供。

即将发布的功能

这一年尚未结束,因此我们还有时间推出更多功能。

Chrome 140 中已可测试范围限定的视图过渡

限定范围的视图转换是 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 伪元素的包含块本来就是快照包含块。唯一可观测到的效果是在执行 getComputedStyleposition 值不同。

document.activeViewTransition即将登陆 Chrome 142

当视图过渡开始时,系统会创建一个 ViewTransition 实例。此对象包含多个 promise 和用于跟踪过渡进度的功能,还允许进行跳过过渡或修改过渡类型等操作。

现在,Chrome 提供了一个表示此对象的 document.activeViewTransition 属性,您无需再手动跟踪此实例。如果没有正在进行的过渡,则其值为 null

对于同文档视图过渡,该值会在您调用 document.startViewTransition 时设置。对于跨文档视图过渡,您可以在 pageswappagereveal 事件中访问该 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 以告知我们。