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

2024 年 Google I/O 大会上,我宣布了视图过渡的下一步:适用于多页面应用 (MPA) 的跨文档视图过渡。

除此之外,我还分享了一些改进功能,让大家可以更轻松地处理视图过渡的总体情况。

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

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

MPA 的跨文档视图转换

浏览器支持

  • 126
  • 126
  • x
  • x

来源

在 Chrome 111 中,Chrome 团队推出了为单页应用实现相同文档视图转换的功能,这是一项在网络构建社区中广受欢迎的功能。

很高兴看到你们中的许多人使用视图过渡构建了构建内容。从“让缩略图变成大照片”的典型实现,到高度定制化的沉浸式体验,比如 Airbnb 的这一切。很好!

与 Airbnb 上一样的文档视图过渡效果。

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

如需启用跨文档视图过渡,两端都需要选择启用。为此,请使用 @view-transition @ 规则,并将 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 共享动画样式

浏览器支持

  • 125
  • 125
  • x
  • x

到目前为止,在以相同的方式为多个快照添加动画效果时,您需要分别定位每个快照,方法是对具有唯一 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 的专用文档

使用活跃类型选择性视图转换

视图过渡的另一项优化是在捕获和执行视图过渡时向视图过渡添加类型。这样可以更轻松地在同一页面上处理各种视图转换,而无需更改彼此的声明。

例如,按分页序列前往下一页或上一页时,您可能需要使用不同的动画,具体取决于您要转到序列中的较高页面还是较低页面。

分页演示的录像。类型决定了要使用的动画。由于有效的过渡类型,样式在样式表中处于分隔状态。

在活动类型之前,您可以向 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