View Transition API 是浏览器原生的视图过渡API,用来实现页面/状态切换的平滑动画,支持 SPA单页应用同文档过渡 和 MPA多页应用跨文档页面跳转动画,属于渐进增强特性:不支持的浏览器直接降级为普通页面跳转,不会破坏业务逻辑。

一、它解决什么痛点

过去网页做切换动画有两个难题:

  1. SPA:路由切换、卡片展开收起,需要手动维护两套DOM、监听位置、写大量JS动画,很容易卡顿;
  2. MPA:多页面跳转时浏览器会销毁旧页面,原生根本无法做跨页面动画。

View Transition交给浏览器处理快照、图层、DOM更新,开发者只需要标记共享元素、写CSS动画,轻松实现App质感的共享元素转场(卡片图片放大到详情页)。

二、工作原理(核心流程)

调用API触发过渡,浏览器自动执行4步:

  1. 捕获旧视图快照:对当前页面生成静态图像快照;
  2. 更新DOM:执行状态变更、路由跳转,渲染新页面DOM;
  3. 捕获新视图快照:拿到新页面图像;
  4. 播放过渡动画:浏览器生成伪元素 ::view-transition-old、::view-transition-new,自动插值做动画。

共享元素原理:给元素设置 view-transition-name: xxx。新旧页面同名元素,浏览器自动做位置、大小的平滑插值,就是大家常看到的「卡片图片放大动画」。

三、两大使用场景

1. SPA 同文档视图过渡(最常用)

调用 document.startViewTransition(()=>{ 更新DOM/路由 })

// 基础示例
if (document.startViewTransition) {
  document.startViewTransition(() => {
    // 这里执行DOM更新,例如路由切换
    renderDetailPage();
  });
} else {
  // 降级方案
  renderDetailPage();
}

给共享图片标记名字:

.card-img {
  view-transition-name: hero-img;
}
.detail-img {
  view-transition-name: hero-img;
}

2. MPA跨文档页面过渡(Level2新增)

不需要JS,同源页面,在前后两个页面CSS都加上:

@view-transition {
  navigation: auto;
}

点击链接跳转,浏览器自动做页面过渡动画,同样支持view-transition-name共享元素。

⚠️限制:仅支持同源网站,跨域页面无法启用MPA过渡。

四、伪元素(CSS自定义动画)

浏览器自动生成一组伪元素,用来自定义动画时长、缓动、效果:

  • ::view-transition:顶层容器
  • ::view-transition-group(name):一组过渡元素容器
  • ::view-transition-old(name):旧页面快照
  • ::view-transition-new(name):新页面快照

示例自定义淡入淡出:

::view-transition-old(hero-img) {
  animation: fade-out 0.3s ease;
}
::view-transition-new(hero-img) {
  animation: fade-in 0.3s ease;
}

五、浏览器支持

  • Chrome / Edge:SPA 111+;MPA跨文档 126+
  • Safari:18+支持SPA;18.2+支持MPA
  • Firefox:144版本支持同文档SPA过渡,MPA尚在完善
  • 属于渐进增强,不支持的浏览器直接忽略动画,业务正常运行。

六、ViewTransition 对象回调(JS监听生命周期)

document.startViewTransition() 返回一个ViewTransition实例,内置Promise:

  • updateCallbackDone:DOM更新完成
  • ready:快照捕获完成,动画即将开始
  • finished:全部动画播放完毕
const transition = document.startViewTransition(()=>render());
transition.ready.then(()=>{
  // 动画准备就绪,可以做额外控制
});
transition.finished.then(()=>{
  // 动画结束
});

七、常见误区

  1. ❌ view-transition-name 不能重复:同一个页面内,view-transition-name必须唯一,多个元素不能同名;
  2. ❌ 不是所有元素都能做共享动画:display:none、脱离文档流、部分遮挡元素无法生成快照;
  3. ❌ MPA只能同源:不同域名之间跳转,无法开启跨文档过渡;
  4. ❌ 不会阻塞页面:动画是在快照图层播放,DOM已经更新完成。

八、适用场景

  • 图库、商品卡片点击放大到详情页(共享元素经典场景)
  • 列表页 ↔ 详情页路由切换动画
  • MPA官网多页面之间平滑转场
  • 表单、弹窗、列表排序等局部状态变化动画

九、框架集成

  • React:React 19 内置 <ViewTransition> 组件封装
  • Vue:Vue Router 可以在导航守卫里调用 startViewTransition
  • Svelte / Solid:原生JS API直接调用

十、总结

View Transition API 是原生Web实现App级转场动画的方案,SPA、MPA都能用,核心优势是不用手写复杂JS动画,浏览器接管快照与图层。利用view-transition-name实现共享元素动画,同时天然支持渐进降级,是现代网站提升UX的重要特性。

十一、Demo