你是否曾经在浏览网页时,被那些丝滑的页面切换效果所吸引——旧内容优雅退场,新内容从容登场,整个过程仿佛电影转场一般自然?如今,借助 CSS 视图过渡 API(View Transitions API),这种体验不再只属于大型框架或复杂脚本,而是可以用几行简洁的 CSS 直接实现。

本文将带你系统了解视图过渡的核心概念,并逐一拆解 7 种可直接复用的过渡动画效果。无论你是想为自己的项目增添一丝灵动,还是希望深入理解视图过渡的工作机制,这份“配方手册”都能为你提供清晰的起点。

一、视图过渡 API 快速入门

视图过渡的核心思想是:当你在两个页面(或同一页面中的两个不同 DOM 状态)之间导航时,浏览器能够捕捉新旧两个状态的视觉快照,然后通过 CSS 动画在它们之间进行平滑过渡。开发者只需要定义动画的样式,浏览器会负责处理快照、分层和渲染。

浏览器支持情况

截至目前(2026.04),Chrome、Edge、Safari 以及 Firefox 都已支持视图过渡功能,可以说是达到了“基线水平”。不过某些高级特性(如自定义过渡类型)在不同浏览器中的表现可能存在细微差异,建议上线前进行充分测试。

基础三步走
1. 定义动画关键帧  

为旧内容(::view-transition-old(root))和新内容(::view-transition-new(root))分别编写 @keyframes 动画。

2. 将动画与过渡类型绑定

通过 :active-view-transition-type() 伪类,让动画只在匹配的过渡类型生效。

3. 启用视图过渡 (可选)

在 CSS 中使用 @view-transition 规则,并声明过渡类型(例如 fade、slide 等)。通常建议放在全局样式或页面模板的头部。这种方式适合全局、静态的过渡效果。

4. 命令式启动过渡(推荐) —— JavaScript 控制

使用 document.startViewTransition 方法可以更灵活地触发过渡,并动态添加过渡类型。尤其适合单页应用(SPA)或根据用户交互决定过渡效果的场景。

💡 两种方式如何选择?

  • 如果你的过渡效果固定、希望浏览器自动捕获传统导航(如点击链接、后退/前进),使用 CSS @view-transition 更简单。

  • 如果需要根据用户操作(点击不同按钮、加载异步内容)动态决定过渡类型或时机,使用 document.startViewTransition 更强大。两者可以混合使用,但建议以 JS 方式为主,以获得最大灵活性。

下面是一个最简配置模板,也是后续所有“玩法集锦”的共同起点。

二、通用基础配置

/* 仅在用户未关闭动效偏好时启用 */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;       /* 自动捕获导航动作 */
    types: <transition-type>; /* 替换为你的过渡类型名,例如 "fade" */
  }
}

/* 绑定动画(以淡入淡出为例) */
html:active-view-transition-type(<transition-type>)::view-transition-old(root) {
  animation: fade-out 0.6s ease forwards;
}

html:active-view-transition-type(<transition-type>)::view-transition-new(root) {
  animation: fade-in 0.6s ease forwards;
}

@keyframes fade-out {
  to { opacity: 0; }
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

注意:<transition-type> 是一个占位符,你需要为每个过渡效果取一个唯一的名字(如 pixelate-dissolve),并确保 @view-transition 中的 types 与 :active-view-transition-type()中的名称完全一致。

三、7 种过渡玩法集锦详解

集锦1:像素化溶解(Pixelate Dissolve)

效果描述

旧页面像被“溶解”一样逐渐模糊并淡出,新页面则从一片模糊中缓缓清晰并淡入。适合营造科技感或梦幻氛围。

实现原理  

利用 filter: blur() 与 opacity 的同步变化,模糊半径从 0 增至 40px,同时透明度归零;新页面则相反。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: pixelate-dissolve;
  }
}

html:active-view-transition-type(pixelate-dissolve)::view-transition-old(root) {
  animation: pixelate-out 1.4s ease forwards;
}

html:active-view-transition-type(pixelate-dissolve)::view-transition-new(root) {
  animation: pixelate-in 1.4s ease forwards;
}

@keyframes pixelate-out {
  0% { filter: blur(0px); opacity: 1; }
  100% { filter: blur(40px); opacity: 0; }
}

@keyframes pixelate-in {
  0% { filter: blur(40px); opacity: 0; }
  100% { filter: blur(0px); opacity: 1; }
}
集锦2:向上擦除(Wipe Up)

效果描述

新页面从底部向上滑动,像擦玻璃一样将旧页面“擦除”。也可以轻松调整为向左、向右或向下擦除。

实现原理

使用 clip-path: inset() 动态裁剪可视区域。旧页面的裁剪下边界从 0% 变为 100%,即从底部开始逐渐隐藏;新页面则从完全裁剪(顶部 100%)恢复到无裁剪。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: wipe-up;
  }
}

html:active-view-transition-type(wipe-up)::view-transition-old(root) {
  animation: wipe-out 1.4s ease forwards;
}

html:active-view-transition-type(wipe-up)::view-transition-new(root) {
  animation: wipe-in 1.4s ease forwards;
}

@keyframes wipe-out {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(0 0 100% 0); }
}

@keyframes wipe-in {
  from { clip-path: inset(100% 0 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

变体技巧:向右擦除只需调整 inset 的第三、四个值:旧页面 inset(0 0 0 100%),新页面 inset(0 100% 0 0)。

集锦3:旋转缩放(Zoom & Rotate)

效果描述

旧页面一边缩小一边顺时针旋转 180 度并淡出;新页面从缩小且逆时针旋转的状态逐渐放大回正。戏剧化效果强烈,适合创意型站点。

实现原理

组合使用 scale() 和 rotate(),并设置 transform-origin: center 确保旋转中心为页面中心。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: zoom-rotate;
  }
}

html:active-view-transition-type(zoom-rotate)::view-transition-old(root) {
  animation: zoom-rotate-out 1.4s ease forwards;
  transform-origin: center;
}

html:active-view-transition-type(zoom-rotate)::view-transition-new(root) {
  animation: zoom-rotate-in 1.4s ease forwards;
  transform-origin: center;
}

@keyframes zoom-rotate-out {
  to { transform: scale(0) rotate(180deg); opacity: 0; }
}

@keyframes zoom-rotate-in {
  from { transform: scale(0) rotate(-180deg); opacity: 0; }
}
集锦4:圆形擦除(Circle Wipe)

效果描述

从页面中心开始,旧页面像一个不断缩小的圆形窗口被“吸走”,新页面则以一个扩大的圆形窗口展开。优雅且富有现代感。

实现原理

利用 clip-path: circle()。旧页面从半径 150% 缩小到 0%;新页面则从 0% 扩大到 150%。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: circular-wipe;
  }
}

html:active-view-transition-type(circular-wipe)::view-transition-old(root) {
  animation: circle-wipe-out 1.4s ease forwards;
}

html:active-view-transition-type(circular-wipe)::view-transition-new(root) {
  animation: circle-wipe-in 1.4s ease forwards;
}

@keyframes circle-wipe-out {
  to { clip-path: circle(0% at 50% 50%); }
}

@keyframes circle-wipe-in {
  from { clip-path: circle(0% at 50% 50%); }
  to   { clip-path: circle(150% at 50% 50%); }
}
集锦5:对角线推入(Diagonal Push)

效果描述

旧页面朝左上角(或任意对角方向)退出,新页面从右下角移入,同时伴随淡入淡出,给人以空间切换的错落感。

实现原理

通过 transform: translate() 在 X 轴和 Y 轴上同时偏移。旧页面偏移 (-100%, -100%),新页面从 (100%, 100%) 回到 (0,0)。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: diagonal-push;
  }
}

html:active-view-transition-type(diagonal-push)::view-transition-old(root) {
  animation: diagonal-out 1.4s ease forwards;
}

html:active-view-transition-type(diagonal-push)::view-transition-new(root) {
  animation: diagonal-in 1.4s ease forwards;
}

@keyframes diagonal-out {
  to { transform: translate(-100%, -100%); opacity: 0; }
}

@keyframes diagonal-in {
  from { transform: translate(100%, 100%); opacity: 0; }
}
集锦6:幕帘揭开(Curtain Reveal)

效果描述

旧页面像左右幕布一样向两侧合拢(实际效果是中间区域收窄),新页面从中央向两侧展开。适合强调“打开新篇章”的意象。

实现原理

旧页面无动画(直接消失),新页面以 inset(0 50% 0 50%) 为起点,即只显示中间一条竖条,然后逐渐扩大到全屏。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: curtain;
  }
}

html:active-view-transition-type(curtain)::view-transition-old(root) {
  animation: curtain-out 1.4s ease forwards;
}

html:active-view-transition-type(curtain)::view-transition-new(root) {
  animation: curtain-in 1.4s ease forwards;
}

@keyframes curtain-out {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(0 50% 0 50%); }
}

@keyframes curtain-in {
  from { clip-path: inset(0 50% 0 50%); }
  to   { clip-path: inset(0 0 0 0); }
}
集锦7:3D 翻转(3D Flip)

效果描述

页面像一张双面卡片一样沿 Y 轴翻转。旧页面翻转到背面“消失”,新页面从背面翻转到正面,立体感十足。

实现原理

使用 rotateY() 和 translateX() 组合,模拟三维空间中的翻页效果。注意需要确保父级容器具有透视(perspective),不过视图过渡的伪元素默认已具备 3D 上下文。

完整代码

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    types: flip-3d;
  }
}

html:active-view-transition-type(flip-3d)::view-transition-old(root) {
  animation: flip-out 1.4s ease forwards;
}

html:active-view-transition-type(flip-3d)::view-transition-new(root) {
  animation: flip-in 1.4s ease forwards;
}

@keyframes flip-out {
  0%   { transform: rotateY(0deg) translateX(0vw); }
  100% { transform: rotateY(-90deg) translateX(-100vw); opacity: 1; }
}

@keyframes flip-in {
  0%   { transform: rotateY(90deg) translateX(100vw); }
  100% { transform: rotateY(0deg) translateX(0vw); }
}

四、进阶小贴士

  • 尊重用户偏好:始终将 @view-transition 包裹在 @media (prefers-reduced-motion: no-preference) 中,避免对运动敏感的用户造成不适。

  • 多过渡类型共存:你可以在不同的页面导航或不同交互中触发不同的 types。例如主页到文章页用“幕帘揭开”,文章页到列表页用“向上擦除”。

  • 调试技巧:在 Chrome DevTools 的 “Rendering” 标签下,可以模拟 prefers-reduced-motion: reduce 来测试降级表现。同时可查看 ::view-transition 伪元素树来观察动画分层。

  • 性能注意事项:避免对 width、height、top、left 等几何属性进行动画,优先使用 transform 和 opacity,以确保动画运行在合成层上,流畅度更高。

总结

视图过渡 API 正在将网页导航体验从“生硬刷新”推向“叙事式转场”。本文提供的 7 种“玩法锦集”涵盖了从简单淡入淡出到 3D 翻转的多种风格,你可以直接复制代码使用,也可以作为创意的起点,调整关键帧、时长、缓动函数,打造属于自己的独特过渡效果。

彩蛋

本文配有完整示例,点击下面列表相应链接即可查看。