abo的博客小站
POST/约 2 分钟

View Transitions API:2 行代码给博客加 SPA 级体验

传统 MPA 切页有一个老大难问题:白屏闪一下。React/Vue 的 SPA 解决了它,但代价是全站 JS 化、SEO 复杂化、bundle 变大。

View Transitions API 给了第三条路。

它是什么

浏览器原生 API(Chrome 111+ / Edge 111+ / Safari 18+ 支持),让多页应用也能像 SPA 一样平滑切换。原理很直白:

  1. 浏览器给旧页面截图
  2. 切到新页面
  3. 给新页面截图
  4. 用 CSS 动画在两张截图之间过渡

整个过程 零额外 JS,性能开销极小。

Astro 怎么用

Astro 5+ 重命名后正式组件叫 <ClientRouter />(旧名 <ViewTransitions /> 仍可用)。把它放进 <head>

---
import { ClientRouter } from 'astro:transitions';
---
<html>
  <head>
    <ClientRouter />
  </head>
  <body>
    <main transition:animate="fade">
      <slot />
    </main>
  </body>
</html>

完事。全站切页自动有 fade 过渡。

内建动画指令

  • transition:animate="fade" —— 淡入淡出(默认)
  • transition:animate="slide" —— 滑动
  • transition:animate="none" —— 禁用过渡
  • transition:persist —— 元素在切页时不重新渲染(适合播放器、表单)

共享元素动画:本站最骚的一处

本站首页文章卡片标题和详情页标题用了 同名 transition:name

<!-- 列表卡片 -->
<h2 transition:name={`post-${post.id}`}>{post.data.title}</h2>

<!-- 详情页标题 -->
<h1 transition:name={`post-${post.id}`}>{post.data.title}</h1>

切页时,浏览器自动让标题从卡片位置 滑动到 详情页标题位置——像 iOS 相册点开图片那种感觉。

尊重用户偏好

API 自动支持 prefers-reduced-motion。用户在系统里关了动效,过渡就降级为普通切页,不会硬塞。

不支持的浏览器?

Firefox 还没全量支持。Astro 会自动降级为普通 MPA 跳转——功能不受影响,只是没有过渡动画。渐进增强的典范。


现在点一下首页的任一文章卡片,看标题的运动轨迹,那就是 View Transitions 在干活。