[控场AI]
· 9 分钟阅读· 4,926 字

View Transitions 重大更新:跨浏览器支持与四大新特性详解

View Transitions 重大更新:跨浏览器支持与四大新特性详解

系统梳理View Transitions近期重要更新:跨浏览器支持扩大、自动命名、嵌套组与作用域过渡全面提升开发体验。

本文基于 Google CSS Podcast 最新一期,系统梳理了 View Transitions 自基础篇以来的重要进展。浏览器支持方面,Chrome 和 Safari 已全面落地同文档与跨文档两种过渡,Firefox 即将跟进。新增的 view transition types 配合 `:active-view-transition-type()` 伪类,可针对不同导航场景精细控制过渡行为。`match-element` 值解决了为大量元素手动命名的痛点,可结合新版 `attr()` 函数实现稳定跨文档标识。Chrome 140 引入的嵌套视图过渡组让父子元素整体协同过渡成为可能;而作用域视图过渡(Canary 可测试)则让过渡只在子树运行,既支持页面多区域同时过渡,又解决了长期存在的整页锁死与 z-index 遮挡问题。

View Transitions(视图过渡)是当下 Web 开发中最令人兴奋的 UI 能力之一,它让开发者能够在网站的两个状态之间创建流畅、无缝的过渡效果,让 Web 应用拥有接近原生应用的体验。在 Google 官方 CSS Podcast 的最新一期中,主持人 Bramus 和 Una 回顾了自基础篇(第 89 期)以来,View Transitions 领域发生的一系列重要变化。本文将系统梳理这些更新。

浏览器支持:从实验到跨浏览器落地

在 View Transitions 刚推出时,只有「同文档视图过渡」(same-document)得到有限支持。如今情况已经大为改观:Chrome 和 Safari 都已同时支持「同文档」与「跨文档」(cross-document)两种视图过渡。

录制节目时,Firefox 也已在 Nightly 版本中开启了同文档视图过渡的标志位,预计将在今年晚些时候推送到稳定版,从而在 Interop 2025 看板上勾选这一项能力。

两个概念需要厘清:同文档视图过渡通过 JavaScript 在同一页面内触发,典型场景是单页应用(SPA)内部的状态切换;跨文档视图过渡则在从一个页面导航到另一个页面时触发,对应多页应用(MPA),也就是我们常说的「普通网站」。

值得关注的是,Firefox 的实现包含了 view-transition-class 属性支持,但暂不支持 view transition types(过渡类型)这一新能力。

Interop 是由苹果、Google、Mozilla、微软等主要浏览器厂商联合发起的年度互操作性项目,旨在针对 Web 平台中浏览器实现不一致的领域进行协同攻坚。每年各厂商会共同商定优先级列表,将某项特性列入 Interop 看板意味着所有参与方均承诺在该年度跟进实现,并以统一测试套件(Web Platform Tests)的通过率作为衡量指标。View Transitions 被纳入 Interop 2025,意味着 Firefox 的稳定版支持预计在 2025 年内落地,届时开发者无需 polyfill 即可在三大主流浏览器上使用该特性。

视图过渡类型:精细化控制过渡行为

View Transition Types 允许你给一次视图过渡指定一个或多个「类型」,并限制某段 CSS 仅在特定类型激活时才生效。这在大型团队协作,或需要根据来源页 / 目标页做不同过渡时尤其有用。

以博客分页为例:在「上一页 / 下一页」之间切换时,你可能希望快照分页组件本身、博文标题,乃至作者头像等相关元素;但当从博文页跳转到「关于」页时,你并不想捕获这些细节,而只想捕获网站 header 和整个内容区。

据主持人介绍,Google 搜索的 AI 模式团队正是这样使用的——在进入或退出 AI 模式时,他们快照界面中较大的构建块作为过渡的一部分;而一旦进入 AI 模式,视图过渡又需要捕获完全不同的元素。developer.chrome.com 上有对应的案例研究可供参考。

As a part of the transition

在语法层面,同文档过渡现在可以向 document.startViewTransition() 传入一个对象,其中包含 callback 和 types(数组)两个属性;跨文档过渡则可在 @view-transition 规则中新增 types 描述符,值为逗号分隔的列表。

设置类型后,可通过新的功能性伪类选择器 :active-view-transition-type() 在 CSS 中响应。它接受类型作为参数,当带有该类型的过渡激活时,选择器会作用于过渡根元素。这个选择器的一大优点是:它从过渡激活的那一刻起就生效——即从旧快照拍摄之前,一直持续到过渡结束。此外还有配套的 :active-view-transition 伪类,用于匹配触发了过渡的元素。

match-element:告别手动命名的烦恼

在用 View Transitions 重建卡片的进入 / 退出动画时,一个明显的痛点是:必须给每一张卡片指定唯一的 view-transition-name,这往往意味着要用 JavaScript 为每张卡片动态生成名称。正如主持人所说:「我只想给每张卡片一个过渡名,但我并不在乎具体是什么名,更不想去管理这些唯一标识符。」

现在有了解决方案——view-transition-name 的特殊值 match-element。它会基于元素的「身份」(identity)自动生成唯一的过渡名。于是,面对 100 张卡片,你不再需要想出 100 个名字,只需一行 .card { view-transition-name: match-element; } 即可。

match element, and you're done

需要注意的限制:该值基于元素的内部编号(浏览器在创建元素时赋予),因此不能用于跨文档过渡,因为不同文档的元素有各自独立的编号。同样,在同文档中移除再插入元素时也会出问题——被移除元素与新建节点的内部编号不同。使用框架时,DOM 树被自动重建也可能导致「看起来相同、实则不同」的元素。

解决办法是借助增强版的 attr() 函数:读取元素的 ID 或 data 属性作为稳定标识。写法类似 attr(id type(<custom-ident>), match-element)——先取属性值并指定类型,若失败则回退到 match-element。主持人直言「希望其他浏览器厂商尽快加入这一强大能力」,或许会出现在 Interop 2026 中。

文中提到的增强版 attr() 函数是 CSS Values Level 5 规范中的新能力,与 CSS 2.1 时代只能返回字符串的旧 attr() 不同,新版支持通过 type() 语法指定返回值类型(如 <custom-ident>、<color>、<length> 等),并接受第二个参数作为回退值。这使得从 HTML 属性读取具有语义类型的值成为可能,从而在 CSS 属性中直接复用元素上已有的业务标识(如 id 或 data-key),避免在 JavaScript 中额外操作样式。目前该特性的浏览器支持仍有限,与 match-element 结合使用时需关注兼容性。

嵌套视图过渡组:尊重 DOM 层级结构

从 Chrome 140 起支持的嵌套视图过渡组(nested view transition groups),允许将一个或多个 view-transition-group 伪元素嵌套进另一个之中。如果你遇到过裁剪问题,或需要让一组元素作为整体在另一个元素内部移动,就会用到它。该特性还支持嵌套 3D 变换,并正确应用 opacity、masking、filter 等效果。

典型例子:一张卡片内含多个头像,当卡片从侧边栏过渡到主列、同时头像也在缩放时,你希望头像作为卡片内容的一部分随之移动。在没有嵌套组之前,卡片与头像的过渡组伪元素会成为「兄弟」关系,而非父子关系,因此无法实现。

individually

要建立嵌套组,需配合新属性 view-transition-group 使用:在父元素上设为 contain,让它容纳所有子元素的快照;或在每个子元素上设为 nearest(寻找最近的带名父元素)或某个匹配父元素名称的自定义标识符。两种写法效果相同,最终在伪元素树中,头像的过渡组会成为卡片过渡组的子级。

不过它们并非直接子级,而是统一分组进一个名为 ::view-transition-group-children 的新伪元素中。若想裁剪内容,需在该新伪元素上设置 overflow: clip。记得使用 Chrome 140 或更新版本来体验相关演示。

作用域视图过渡:仅在子树上运行

如果你只想在单个父元素内部做裁剪,那么比嵌套组更合适的,是目前在 Chrome Canary 中可测试(需开启 experimental web platform features 标志)的作用域视图过渡(scoped view transitions)。官方正在积极征集反馈。

它的核心变化是:不再调用 document.startViewTransition(),而是调用 element.startViewTransition()。整个过渡子树只会注入到该元素上,而非整个文档。其余逻辑与常规同文档过渡一致,但关键区别在于——view-transition overlay 伪元素注入到调用元素上,使得过渡运行时页面其余部分仍可交互。这解决了 View Transitions 一直以来「过渡运行时整页卡住」的痛点。

running a view transition on only a sub-tree

作用域过渡还带来几个有价值的「副作用」:一是可以让多个过渡同时运行,只要它们位于不同子树(例如聊天组件和 header 同时过渡);二是缓解了长期困扰开发者的 z-index 问题。此前,过渡伪元素会绘制在整个文档(包括 top layer)之上,导致 popover 等元素被意外遮挡,开发者不得不给 popover 也加上过渡名作为 hack;现在大多数情况下无需再这么做。三是内容会自动裁剪。

需注意的差异是:使用作用域过渡时,容器本身不会随过渡移动;而嵌套视图过渡组则会。主持人给出的当前经验法则是:先尝试用作用域过渡解决问题,若不行再考虑嵌套视图过渡组——当然最佳实践仍在探索中。

Top layer(顶层)是浏览器渲染模型中一个特殊的独立层,<dialog>、popover 属性元素、全屏元素等都会被提升到该层渲染,确保它们始终显示在页面其余内容之上,不受 z-index 和 overflow: hidden 的影响。然而传统的 View Transitions 过渡伪元素会被绘制在整个文档的最顶部,甚至覆盖 top layer,导致本应置顶的 popover 和模态框在过渡动画期间被遮挡。作用域视图过渡将伪元素注入到指定子元素而非 <html> 根节点,从根本上规避了与 top layer 的层叠冲突,是解决该问题的正式方案。

其他:document.activeViewTransition

最后一个较小的新增是正在开发中的 document.activeViewTransition 属性。它让你能直接访问当前激活的视图过渡对象(如果存在的话)。此前要实现这一点,你需要在启动过渡时自行记录追踪,今后将不再需要。录制节目时该属性尚未进入任何浏览器,但预计很快会出现在 Canary 甚至 Chrome Stable 中。

小结

View Transitions 正从「有趣的实验特性」快速演进为「生产可用的 UI 能力」。跨浏览器支持的扩大、match-element 对开发体验的改善、嵌套组与作用域过渡对复杂场景的覆盖,都在让 Web 应用更接近原生的流畅体验。对于想让网站「morph」得更自然、更 appy 的开发者而言,现在正是深入学习它的好时机。

#View Transitions#视图过渡#CSS动画#match-element#作用域视图过渡#嵌套视图过渡组#Chrome 140#前端开发
分享:

相关推荐