view transitions api 是导航级过渡机制,非 css 动画替代品;需显式调用 document.startviewtransition() 包裹 dom 更新(非导航本身),配合 ::view-transition-old/new 伪元素实现遮罩,且仅在客户端路由跳转时生效。

View Transitions API 不是 CSS 动画替代品,而是导航级过渡机制
它不靠 transition 或 @keyframes 实现遮罩效果,而是由浏览器在页面导航(如 history.pushState、router.push)时自动捕获 DOM 变化,并对「旧元素」和「新元素」分别生成快照,再用合成层做过渡。遮罩感需手动叠加伪元素或 backdrop —— 它本身不提供遮罩层。
必须显式开启 View Transition 并包裹更新逻辑
直接写 document.startViewTransition(() => { location.href = '/next' }) 会失败:现代框架(如 Vue Router、React Router v6.22+)默认禁用原生 View Transitions;纯 HTML 导航也不触发。正确做法是:
- 确保启用条件:Chrome 111+、Edge 111+,且页面无
document.domain修改 - 用
document.startViewTransition()包裹 DOM 更新动作,不是导航动作本身 - 在单页应用中,应在路由守卫或组件挂载后调用,例如 Vue 中:
onMounted(() => { document.startViewTransition(() => { // 触发数据更新或 class 切换,让视图重渲染 isActive.value = true }) })
遮罩效果要靠 ::view-transition-old() 和 ::view-transition-new() 配合 backdrop-filter 或伪元素
想实现「淡入遮罩」,不能只动 opacity:浏览器会把旧/新内容作为独立合成层处理,需主动控制它们的堆叠与视觉样式。常见组合:
- 给旧内容加半透明黑色背景:
::view-transition-old(root) { background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(2px); } - 用
::view-transition-group控制整体缩放/位移,避免遮罩“撕裂”:::view-transition-group { clip-path: inset(0); transform: scale(0.98); } - 禁止默认 fade 效果干扰遮罩:显式重置
opacity,否则旧元素可能提前消失:::view-transition-old(root), ::view-transition-new(root) { opacity: 1 !important; }
服务端渲染(SSR)和静态站点要注意生命周期时机
在 DOMContentLoaded 之前调用 startViewTransition 会报错 InvalidStateError: No active navigation;而 SSR 页面首次加载时没有「导航上下文」,View Transitions 不生效。实际方案:
- 仅在客户端路由跳转时启用,服务端首屏不触发过渡
- 监听
navigation事件而非点击事件:navigation.addEventListener('navigate', (e) => { e.intercept(async (interception) => { document.startViewTransition(() => interception.commit()); }); }); - 若用 Astro / SvelteKit,需在
onMount中检查document.activeElement是否为 body,避免 hydration 冲突
遮罩过渡真正难的不是写几行 CSS,而是理解 View Transitions 的触发边界 —— 它只在「一次导航 + 一次 DOM 更新」的原子操作中有效,跨框架状态同步、异步数据加载、CSS-in-JS 注入顺序,都可能让它静默失效。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











