视图转换有哪些新变化?(2024 年 Google I/O 大会更新)

发布时间:2024 年 5 月 16 日

2024 年 Google I/O 大会上,我宣布了视图转换的下一步发展:针对多页应用 (MPA) 的跨文档视图转换。

除此之外,我还分享了一些改进,让您能够更轻松地处理常规的视图过渡。

  • 使用 view-transition-class 在视图过渡伪元素之间共享动画样式。
  • 具有有效类型的选择性视图转换。

这些改进适用于单页应用 (SPA) 的同文档视图转换和 MPA 的跨文档视图转换。

针对 MPA 的跨文档视图过渡

Browser Support

  • Chrome: 126.
  • Edge: 126.
  • Firefox: not supported.
  • Safari: 18.2.

Source

在 Chrome 111 中,Chrome 团队推出了单页应用的同文档视图转换,这项功能在 Web 构建社区中广受好评。

很高兴看到许多开发者利用视图过渡功能构建了各种各样的应用。从“使缩略图放大为大照片”的典型实现到高度自定义的沉浸式体验(例如 Airbnb 的这种体验),应有尽有。很好!

与 Airbnb 上看到的相同的文档视图过渡效果。

不过,最初的实现要求您构建 SPA 才能使用视图过渡。从 Chrome 126 开始,情况不再如此,现在默认针对同源导航启用视图过渡。您现在可以在两个同源的不同文档之间创建视图过渡。

如需启用跨文档视图过渡,两端都需要选择启用。为此,请使用 @view-transition at 规则并将 navigation 描述符设置为 auto

@view-transition {
  navigation: auto;
}

跨文档视图过渡与同文档视图过渡使用相同的构建块和原则。系统会捕获应用了 view-transition-name 的元素,您可以使用 CSS 动画自定义动画。

如需自定义跨文档视图过渡,请使用 pageswappagereveal 事件,以便访问视图过渡对象。

  • 借助 pageswap,您可以在拍摄旧快照之前对即将退出的网页进行一些临时更改。
  • 借助 pagereveal,您可以在新网页初始化后、开始渲染之前对其进行自定义。

在这两种事件中,您都可以访问 NavigationActivation 对象,以根据旧的和新的目标历史记录条目或导航类型自定义跨文档视图过渡

最重要的是,您可以通过阻塞渲染等待内容加载,并依靠预渲染来缩短视图转换运行之前的加载时间。

演示

Stack Navigator 演示结合了所有这些功能(以及一些改进)。

Stack Navigator 演示的录制视频。它使用在 pagereveal 事件中根据导航激活信息自定义的跨文档视图过渡。此外,还使用了预渲染。

这是一个具有跨文档导航功能且托管在同一来源上的 MPA。通过使用 pagereveal,系统会根据旧的和新的目的地历史记录条目来确定动画类型。

window.addEventListener("pagereveal", async (e) => {
  if (e.viewTransition) {
    // Determine animation type based on the old/new history entries
    const transitionClass = determineTransitionClass(navigation.activation.from, navigation.currentEntry);
    document.documentElement.dataset.transition = transitionClass;

    // Cleanup after transition ran
    await e.viewTransition.finished;
    delete document.documentElement.dataset.transition;
  }
});

阅读文档

如需详细了解如何启用和自定义跨文档视图过渡效果,请参阅我们的跨文档视图过渡效果文档


视图过渡改进

除了为 MPA 提供跨文档视图过渡之外,Chrome 还对视图过渡的常规使用方式进行了一些改进。

这些改进适用于 SPA 的同文档视图过渡和 MPA 的跨文档视图过渡。

view-transition-class 分享动画样式

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: 144.
  • Safari: 18.2.

Source

在此之前,如果需要以相同方式为多个快照添加动画效果,您需要针对每个具有唯一 view-transition-name 的元素重复使用伪选择器,从而单独定位每个快照。

借助 view-transition-class,您现在可以为所有快照添加共享名称。在伪选择器中使用此共享名称可定位所有匹配的快照。这样一来,选择器会简单得多,并且可以自动从一个元素扩展到多个元素。

#cards-wrapper > div {
  view-transition-class: card;
}
html::view-transition-group(.card) {
  animation-timing-function: var(--bounce);
}

以下卡片示例使用 view-transition-class 通过一个选择器将相同的动画时间应用于多个快照。

卡片演示的录制内容。使用 view-transition-class 时,系统会将相同的 animation-timing-function 应用于所有卡,但添加或移除的卡除外。

如需详细了解 view-transition-class,请阅读有关 view-transition-class 的专用文档

具有有效类型的选择性视图转换

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: 144.
  • Safari: 18.

Source

视图过渡的另一项改进是在捕获和执行视图过渡时,可以向视图过渡添加类型。这样一来,您就可以更轻松地在同一网页上使用各种视图过渡效果,而无需声明一个视图的更改会影响另一个视图。

例如,在分页序列中前往下一页或上一页时,您可能希望根据前往的页面是序列中的较高页面还是较低页面来使用不同的动画。

分页演示的录制视频。
类型决定了要使用的动画。由于采用了有效的过渡类型,样式表中的样式得以分离。

在引入活动类型之前,您可以向 DOM 添加类,并在 CSS 中响应这些类。不过,您还必须在转换完成后进行清理。

借助视图过渡类型,您可以实现相同的效果,而且这些类型在视图过渡完成后会自动清理,这是额外的优势。类型仅在捕获或执行过渡时适用。

对于同文档视图过渡,types 传递给现在接受对象的 startViewTransition 方法update 是用于更新 DOM 的回调函数,types 是一个字符串序列。

const direction = determineBackwardsOrForwards();

const t = document.startViewTransition({
  update: updateTheDOMSomehow,
  types: ['slide', direction],
}););

对于跨文档视图过渡,请使用 types 描述符在 @view-transition @ 规则中设置类型,或在 pageswappagereveal 事件中动态设置类型。

@view-transition {
  navigation: auto;
  types: slide, forwards;
}

设置类型后,您可以使用 :active-view-transition-type():active-view-transition 伪类选择器在 CSS 中响应这些类型,这些选择器适用于视图过渡根。

/* Animation styles for forwards type only */
html:active-view-transition-type(forwards) {
  &::view-transition-old(content) {
    animation-name: slide-out-to-left;
  }
  &::view-transition-new(content) {
    animation-name: slide-in-from-right;
  }
}

如需详细了解视图过渡类型,请参阅有关同文档视图过渡跨文档视图过渡的专用文档。


反馈

我们随时欢迎开发者的反馈。为此,请在 GitHub 上向 CSS 工作组提交问题,并附上建议和问题。在问题前添加 [css-view-transitions] 前缀。

如果您遇到 bug,请改为提交 Chromium bug