
CSS 视图过渡的入门级指南
想象一下,您的网站可以在页面之间流畅地进行动画,将您从index.html
导航到about.html
,而无需令人不适的页面重新加载。现在,这已经成为可能,这得益于现代浏览器对视图转换 API的支持。
视图转换曾经是单页应用程序(SPA)独有的功能。在这篇文章中,我们将探讨视图转换如何为多页应用程序(MPA)带来流畅、动画化的导航。
MPA 与 SPA 快速回顾
多页应用程序(MPA)和单页应用程序(SPA)是两种常见的 Web 开发方法,它们各有优缺点。
- MPA 在每次导航时都会从服务器加载一个新页面,导致整个页面重新加载。对于包含许多不同页面的大型应用程序,MPA 更易于构建。
- 另一方面,SPA 加载单个 HTML 页面,并通过 JavaScript 动态更新其内容,提供更快的交互和更流畅的用户体验,但通常需要更复杂的客户端路由和状态管理。
长期以来,流畅的动画过渡只能在 SPA 中实现。现在,借助视图转换 API——以及 CSS 的 @view-transition
at-rule——MPA 也可以实现类似的效果。CSS 视图转换的设计理念是渐进增强。因此,如果浏览器不支持它们,网站仍然可以正常工作,因为 CSS 被视为一个提示,并且只在支持时应用。
浏览器对视图转换的支持
在深入探讨此功能的具体用法之前,值得注意的是视图转换目前的支持情况。CSS 视图转换规范有两个级别:
- Level 1 使用 视图转换 API 在单个页面内实现转换。这在 Chrome、Edge 和 Safari 中已经得到支持。Firefox 版本 144(目前处于 Beta 版)也支持该功能。
- Level 2 允许通过
@view-transition
at-rule 实现跨多页面的转换。它目前在 Chrome 126+、Edge 126+ 和 Safari 18.2+ 中得到支持。在撰写本文时,Level 2 在 Firefox 中仍处于开发过程中,但预计将来会获得支持。
在不支持视图转换的浏览器中,网站将继续正常运行,使用标准的页面导航,因为这些转换被视为渐进增强,不会破坏您的网站。
创建您的第一个视图转换
让我们深入了解一下,看看视图转换的实际应用。
作为最简单的例子,您只需在代码中添加几行 CSS 即可启用转换。
@view-transition {
navigation: auto;
}
就是这样!基本版本只需要几行 CSS,如果问我的话,这简直太棒了。
为了看到这行代码的效果,让我们构建两个演示页面。您也可以尝试将此代码添加到任何现有的多页应用程序中。
第一个页面index.html
,只包含一个标题、一些段落和一个指向第二个页面的链接。
<h1>🏡 Homepage</h1>
<p>Hello, my name is Mrs. Whiskers. Welcome to my personal website!</p>
<p>
Everyone needs a place on the web, even a cat. If you're curious, you can find
out more about my <a href="hobbies.html">hobbies</a>.
</p>
准备好我们的第二个页面hobbies.html
。这也是一个简单的页面,包含一个标题、两个简短的段落以及一个返回第一个页面的链接。
<h1>🧶 My hobbies</h1>
<p>
When I'm not busy napping, I love to play with yarn and chase laser pointers.
I'm also an avid bird watcher.
</p>
<p>
Thank you for your interest! You can return to the
<a href="index.html">homepage</a> now.
</p>
最后,将以下样式添加到您的style.css
文件中。
@view-transition {
navigation: auto;
}
这就是创建视图转换所需的全部内容。仅凭这一行 CSS,您就会看到两个页面之间无缝的过渡。过去,这种流畅的过渡只能通过 JavaScript 在 SPA 中实现。借助 CSS @view-transition
at-rule,浏览器现在可以原生处理多页应用程序之间的转换,而无需 JavaScript。
超越默认转换
现在让我们更进一步,自定义视图转换。在这里,我们将创建一个滑动进入和滑动出去的效果,这是一个简单的动画,用于理解视图转换的内部工作原理。
让我们为我们的两个 HTML 页面添加两个不同的样式表。将此添加到index.html
。
<link rel="stylesheet" href="index.css" />
……将此添加到hobbies.html
。
<link rel="stylesheet" href="hobbies.css" />
是时候熟悉一些控制视图转换的 CSS 选择器(伪元素)了。
::view-transition-old(root),
::view-transition-new(root) {
/* Write some cool CSS here */
}
让我们了解一下这些伪元素是如何工作的:::view-transition-old 和 ::view-transition-new 伪元素分别引用旧页面和新页面,使我们能够为它们之间的过渡设置样式。当我们从index.html
导航到hobbies.html
时,旧页面是我们正在离开的页面(index.html
),新页面是我们即将前往的页面(hobbies.html
)。
让我们添加一个滑动动画,让hobbies.html
以平滑的滑动效果进入。我们将此动画称为 slide-from-right。将以下代码添加到hobbies.css
。
@keyframes slide-from-right {
from {
/* Arrive from the right */
transform: translateX(100vw);
}
to {
/* Come into view */
transform: translateX(0);
}
}
::view-transition-old(root),
::view-transition-new(root) {
mix-blend-mode: normal;
}
::view-transition-old(root) {
animation: none;
}
::view-transition-new(root) {
/* Apply animation to hobbies.html */
animation: slide-from-right 0.3s;
}
请注意,mix-blend-mode
被设置为 normal
,以避免默认的交叉淡入淡出效果。默认情况下,视图转换使用 plus-lighter
混合模式在旧页面和新页面之间创建交叉淡入淡出效果,但对于滑动动画,我们不需要这种交叉淡入淡出,因此我们用 normal
来覆盖它。
滑动进入效果如下所示。
现在,让我们通过添加另一个滑动动画来完成此效果,以确保hobbies.html
页面以其进入的方式滑出。在这种情况下,我们将从hobbies.html
导航到index.html
;因此,hobbies.html
现在是我们的旧页面,index.html
是新页面。
我们将此动画称为 slide-to-right
。将此代码添加到index.css
。
@keyframes slide-to-right {
from {
/* Start from screen view */
transform: translateX(0);
}
to {
/* Move to right */
transform: translateX(100vw);
}
}
::view-transition-old(root),
::view-transition-new(root) {
mix-blend-mode: normal;
}
::view-transition-old(root) {
/* Apply @keyframes to hobbies.html */
animation: slide-to-right 0.3s;
z-index: 2;
}
::view-transition-new(root) {
animation: none;
}
请注意,我在两个方向上都只为hobbies.html
添加了动画,而没有为index.html
添加任何动画。如果您愿意,也可以为两者都添加动画。
最终的过渡效果如下,包括hobbies.html
的滑动进入和滑动出去效果。
在您的浏览器中查看演示页面以查看效果。如果您想扩展此演示,请随时使用 mdn/dom-examples 存储库中的代码,并为index.html
页面添加动画(在index.css
文件中查找 animation: none
)。
我很乐意看到您构思出的所有酷炫的视图转换。
总结
您可以在 MDN 的 Mastodon 上观看我关于此主题的演讲视频。
祝您视图转换愉快!愿您的多页应用程序在页面之间流畅切换。