CSS View Transitions API页面过渡动画与跨文档导航实现

View Transitions API核心机制

CSS View Transitions API为Web应用提供了原生级别的页面过渡动画能力,无需依赖JavaScript动画库或Canvas渲染。该API在Chrome 111+和Firefox 128+中已稳定支持,核心思路是浏览器自动捕获新旧页面的视觉快照,在快照之间执行可自定义的过渡动画。

工作原理分四步:浏览器对当前页面状态生成旧快照(old snapshot);执行DOM更新操作;对新页面状态生成新快照(new snapshot);在两个快照之间运行动画。整个过程由浏览器合成器驱动,动画帧率稳定在60fps,不阻塞主线程。

同文档视图切换过渡

同文档内的视图切换是最简单的应用场景,例如SPA中的Tab切换或列表/详情视图切换:

document.startViewTransition(() => {

detailPanel.classList.remove("hidden");

listPanel.classList.add("hidden");

});

浏览器自动为发生变化的元素生成默认的淡入淡出动画。自定义过渡效果通过CSS伪元素控制:

::view-transition-old(root) {

animation: 300ms ease-out both fade-out;

}

::view-transition-new(root) {

animation: 300ms ease-in both fade-in;

}

root伪元素代表整个页面的过渡,适用于全局性视图切换。当需要更精细的控制时,给目标元素设置view-transition-name:

.user-avatar {

view-transition-name: avatar;

}

::view-transition-old(avatar) {

animation: 250ms ease-in-out both scale-down;

}

::view-transition-new(avatar) {

animation: 250ms ease-in-out both scale-up;

}

view-transition-name相同的元素在快照之间建立配对关系,浏览器自动计算它们的位置差异并生成插值动画。这一机制使共享元素过渡(Shared Element Transition)成为可能——头像从列表位置飞到详情页位置。

跨文档导航MPA过渡

View Transitions API同样支持多页面应用(MPA)的跨文档导航。Chrome 124+实现了跨文档视图过渡,无需JavaScript即可实现页面切换动画:

在CSS中声明导航过渡:

@view-transition {

navigation: auto;

}

此声明使浏览器在所有同源页面导航时自动触发视图过渡。配合view-transition-name实现跨页面的元素动画配对:

列表页中:

.card-image { view-transition-name: card-img-1; }

详情页中:

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

当从列表页导航到详情页时,卡片图片会自动飞到详情页英雄图的位置,其余元素做默认淡入淡出。

控制特定导航类型的过渡行为:

@view-transition {

navigation: auto;

}

@media (prefers-reduced-motion: reduce) {

@view-transition { navigation: none; }

}

共享元素过渡动画实践

共享元素过渡(也叫Hero Animation)是View Transitions API最有价值的应用。实现一个从列表到详情的Hero过渡:

列表页HTML结构:

<div class="card" onclick="navigateToDetail(1)">

<img class="card-img" src="photo1.jpg" style="view-transition-name: item-1-img" />

<h3 style="view-transition-name: item-1-title">标题文本</h3>

</div>

JavaScript动态设置transition name:

function navigateToDetail(id) {

const img = document.querySelector(`.card-img[data-id="${id}"]`);

img.style.viewTransitionName = "detail-img";

const title = document.querySelector(`.card-title[data-id="${id}"]`);

title.style.viewTransitionName = "detail-title";

if (document.startViewTransition) {

document.startViewTransition(() => {

updateDOMForDetailView(id);

});

} else {

updateDOMForDetailView(id);

}

}

详情页的对应元素也设置相同的view-transition-name,浏览器自动计算位置差异并生成平滑飞入动画。

性能优化与降级方案

View Transitions动画由浏览器合成器执行,不触发主线程重排重绘,性能开销极低。但仍需注意:view-transition-name值在页面中必须唯一,重复的name会导致过渡失效;避免对大量元素同时设置独立的transition name,合成器为每个独立配对创建独立的合成层,过多层导致GPU显存压力。

降级策略:不支持View Transitions API的浏览器中startViewTransition为undefined,需做特性检测后降级为即时DOM更新:

const update = () => { /* DOM更新逻辑 */ };

document.startViewTransition ? document.startViewTransition(update) : update();

prefers-reduced-motion媒体查询需始终尊重,为运动敏感用户提供无动画的即时切换体验。在动画执行期间,浏览器在旧快照上层渲染新快照,交互事件被新快照接收,不会出现点击穿透问题。过渡期间的长任务会延迟快照捕获,建议在startViewTransition回调中避免繁重的DOM操作,保持回调执行在50ms以内。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/cssviewtransitionsapi-ye-mian-guo-du-dong-hua-yu-kua-wen/

(0)
小编小编
上一篇 8小时前
下一篇 8小时前

相关推荐