SPA 视图转换在 Chrome 111 中推出

Jake Archibald
Jake Archibald

借助 View Transition API,您可以一步更新 DOM,同时在两种状态之间生成动画过渡。

使用 View Transition API 创建的转换。试用演示网站 - 需要 Chrome 111 或更高版本。

包括我在内的开发者经常请求添加此类转场效果,我们认为自己在实现此功能时,很好地平衡了良好的默认设置与可扩展性和自定义性。这听起来像是在自夸,但开发者 反馈在设计此功能时至关重要。此功能的早期原型灵活性要低得多,而那些抽出宝贵时间来试用原型并提供反馈的用户(比如您?)促使我们彻底重新思考。谢谢!

如需快速上手使用此功能并试用一些演示,请参阅我们的指南。如果您认为该文档未涵盖某些内容,请通过 TwitterMastodon电子邮件与我联系。

View Transitions API 目前仅适用于 Chrome;幸运的是,它可以用作渐进式增强功能。该指南包含一个辅助函数,您可以在所有浏览器中使用该函数,但只有支持视图转换的浏览器才能获得动画效果。

我们在 CSS 工作组中开发了这项功能,并征求了其他浏览器供应商和独立开发者的意见。我们不知道其他浏览器是否会采用 View 转换,也不知道何时会采用,但请密切关注 Mozilla 的标准位置WebKit 的标准位置

不过,我们还没有“完成”!

在 Chrome 111 中推出的功能只是首次发布。我们希望已经找到所有 bug,但如果您发现任何问题,请前往 crbug.com 提交,最好附上精简版演示。如果您不熟悉或不习惯这种方式,可以通过 TwitterMastodon电子邮件与我联系,我会为您提供帮助。

此版本只是大局中一小部分,但希望能对您有所帮助。我们已经勾勒出此功能的一些扩展,以确保我们今天发货的部件能够在未来使用。

下面是我们的一些想法,供您抢先了解。这些功能并非按优先级排序(不过,对于许多人来说,第一个功能可能是最重要的),因此我们非常期待收到有关哪些新增功能对您来说最重要方面的反馈。

跨文档转场

我认为这是大多数开发者希望我们接下来着手解决的问题,好消息是,我们已经在努力解决这个问题了!

View Transitions API 的设计使其能够在同源文档中运行。唯一的区别在于,导航本身会发出 DOM 状态更改信号,而不是 startViewTransition

这是我们在 chrome://flags/#view-transition-on-navigation 标志后面实现的原型。下面是一个超简单的演示和一个更复杂的演示

为了继续推进,我们需要了解每个网页如何选择启用过渡。目前,我们使用的是元标记:<meta name="view-transition" content="same-origin">,但我们认为 CSS 更适合用于此目的。我们还希望让您更轻松地了解自己要从哪种类型的页面进行转换,最好是无需编写 JavaScript 即可。

我们还有许多工作要做,因此更希望以“正确”的方式实现此功能,而不是“快速”实现,但这绝对是我们的优先事项。

由合成器驱动的动画

我们默认选择对转场组的宽度和高度进行动画处理,因为这样更容易进行自定义。不过,这意味着动画会在主线程上运行,这并不理想,尤其是在网页加载期间。

我们计划检测默认动画和常见自定义项,然后将其重新解释为由合成器驱动的动画,以大幅提升性能。

作用域转换

目前,SPA 转换的范围是整个文档,并且一次只能运行一个转换。我们希望引入一项功能,让转场效果可限定为特定元素,以便多个页面组件可以独立运行转场效果。

例如,这样一来,嵌入式视频播放器就可以在嵌入式聊天 widget 的同时使用视图转换。

嵌套的转换组

目前,所有 ::view-transition-group 都是兄弟姐妹。这通常是件好事,因为它允许视图从一个容器转换到另一个容器,而您无需担心剪裁问题。

不过,有时您希望某个视图被某个父视图剪裁,该父视图可能也参与了转场。

我们想要调查一种可选功能,该功能会将特定 ::view-transition-group 放置在另一个 ::view-transition-group 中。

转场类

每个 view-transition-name 都必须是唯一的。这样,我们就可以确定特定元素在 DOM 更改的任一侧在概念上都是“相同”的,即使它们在字面上不是同一个元素也是如此。

不过,有时具有不同 view-transition-name 的对象应使用相同类型的动画。目前,这意味着为每个 view-transition-name 添加一个选择器规则。

我们希望添加一种创建转场类的方法来克服此限制。

忽略屏幕外元素

如果您为某个元素设置了 view-transition-name,则该元素将作为自己的组参与转换。但有时,这种做法并不理想。例如,如果您为标题添加 view-transition-name,并且从向下滚动 2000 像素的状态切换到页面顶部的状态,标题将从 2000 像素处开始动画,这在时间方面会感觉不对。

我们希望添加一个可选功能,如果某个元素完全位于视口之外,则系统会忽略该元素,就像该元素没有 view-transition-name 一样。

您已经可以通过 JavaScript 动态设置 style.viewTransitionName 来实现此目的,但我们似乎应该为此提供声明式解决方案。

requestAnimationFrame 驱动的动画

您已经可以通过 Web 动画 API 使用 JavaScript 创建视图转场动画,但有时您需要使用 requestAnimationFrame 逐帧驱动动画。

您已经可以这样做了,但方法有点不太妥当。此演示包含一些可能对您有用的帮助程序。我们希望使其不那么粗糙!

我们将分两个部分完成此操作。第一种方法是提供一个 API 来指示动画何时结束。其次,通过向 JavaScript 提供对伪元素的访问权限。第二部分可能是一个非常大的任务,但从长远来看,这似乎是正确的做法。

现在,您可以制作一些精彩的视图转换了!

希望您和我一样,对这项功能的现在和未来充满期待。如果您有任何反馈,或者只是想展示您制作的一些视图转换(无论是流畅实用的,还是只是单纯 愚蠢的),请在 Twitter 上与我联系或通过 Mastodon 与我联系!