你是否曾经在浏览网页时,被那些丝滑的页面切换效果所吸引——旧内容优雅退场,新内容从容登场,整个过程仿佛电影转场一般自然?如今,借助 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 翻转的多种风格,你可以直接复制代码使用,也可以作为创意的起点,调整关键帧、时长、缓动函数,打造属于自己的独特过渡效果。
彩蛋
本文配有完整示例,点击下面列表相应链接即可查看。