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

发布时间:2024 年 5 月 16 日

2024 年 Google I/O 大会上,我宣布了视图转换的后续步骤:为多页面应用 (MPA) 实现跨文档视图转换。

此外,我还分享了一些改进,让您能够更轻松地处理一般视图转换。

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

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

MPA 的跨文档视图转换

浏览器支持

  • Chrome:126.
  • Edge:126。
  • Firefox:不受支持。
  • Safari Technology Preview:受支持。

在 Chrome 111 中,Chrome 团队发布了适用于单页应用的同文档视图转换,该功能在 Web 构建社区中广受欢迎。

很高兴看到许多开发者使用 View 转换构建了哪些内容。从“让缩略图放大为大照片”的典型实现,到 Airbnb 提供的这种高度自定义的沉浸式体验,不一而足。很好!

与 Airbnb 上显示的同一文档视图转换。

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

如需启用跨文档视图转换,需要同时在发起端和接收端选择启用。为此,请使用 @view-transition at-rule 并将 navigation 描述符设置为 auto

@view-transition {
  navigation: auto;
}

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

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

  • 借助 pageswap,您可以在系统拍摄旧快照之前,对即将退出使用的网页进行一些最后一刻的更改。
  • 借助 pagereveal,您可以在新页面初始化后开始呈现之前对其进行自定义。

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

最后,您可以使用呈现阻塞功能等待内容加载,并依赖于预渲染,以缩短视图转换运行前的加载时间。

演示

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 共享动画样式

浏览器支持

  • Chrome:125。
  • 边缘:125。
  • Firefox:不受支持。
  • Safari Technology Preview:受支持。

到目前为止,如果您要以相同的方式为多个快照添加动画效果,则需要为具有唯一 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 的专用文档

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

浏览器支持

  • Chrome:125.
  • 边缘:125。
  • Firefox:不受支持。
  • Safari:18.

视图转换的另一个优化是引入了在捕获和执行视图转换时向视图转换添加类型。这样,您就可以更轻松地在同一页面上处理各种视图转换,而不会因一个声明而更改另一个声明。

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

分页演示的录制内容。类型决定了要使用的动画。由于采用了有效的转换类型,样式在样式表中是分开的。

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

使用视图转换类型时,您可以实现相同的结果,而且这些类型的额外优势会在视图转换完成后自动清理。类型仅在捕获或执行转场时应用。

对于同一文档内的视图转换,请types 传入 startViewTransition 方法,该方法现在接受对象。update 是用于更新 DOM 的回调函数,types 是字符串序列。

const direction = determineBackwardsOrForwards();

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

对于跨文档视图转换,请使用 types 描述符在 @view-transition at-rule 中设置类型,或在 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] 前缀。

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