查看原文
科技新闻

【第3017期】开始在多页面应用程序上使用视图过渡

飘飘 前端早读课 2023-08-02

前言

介绍了如何在多页面应用(MPA)和静态网站中使用视图过渡(View Transitions)。首先通过在 Chrome 浏览器中启用标志来实现视图过渡功能。然后介绍了如何在网站的全局 <head> 标签中添加一个简单的 < meta > 标签来启用页面过渡效果。接下来,讲解了如何通过为特定元素添加相同的视图过渡名称来实现具体的元素过渡效果,以及如何在 CSS 中自定义过渡效果。文章还提到了一些技术的限制和解决方案。最后,作者强调了这种技术的优势和进步增强的特点,并期待其他浏览器也能支持这一功能。今日前端早读课文章由 @飘飘翻译分享。

正文从这开始~~

受上周的 ShopTalk 启发,我在我的静态 Jekyll 网站上使用了视图过渡。我之前没有意识到在 Chrome 113+ 中,多页面应用(MPAs)和静态网站的视图过渡功能已经可以在测试标志下使用。视图过渡对于我来说是 CSS 心愿清单上的一个重要功能,所以我立即尝试了一下。只花了不到一个小时的时间,不需要任何 JavaScript,只需要两行 CSS。我对结果感到满意。

⚠️ 在撰写本文时,这项功能只在 Chrome Canary 115+ 版本中有效。我无法为其他浏览器修复此问题。对于默认未启用多页面视图过渡功能的浏览器(实际上是所有其他浏览器),你的页面将像正常页面一样加载。这个技术是一种令人惊叹的渐进增强技术。

现在让我们开始为网站添加视图过渡效果...

在 Chrome Canary 中启用标志

要开始使用视图过渡功能,请在 Chrome Canary 中启用它们。

chrome://flags#view-transition
chrome://flags#view-transition-on-navigation

⚠️ 这些标志在 Chrome 稳定版和 Arc(但不包括 Edge)中也存在,但页面可能会随机锁定,所以建议使用 Canary 版本,或者等到 Chrome 稳定版于 2023 年 7 月 12 日左右发布 v115。目前还没有官方宣布未来版本是否会取消对这些标志的设置。

现在我们来到有趣的部分...

添加视图过渡的 meta 标签

在你的布局模板的全局 <head> 标签中添加以下内容。

<meta name="view-transition" content="same-origin" />

恭喜,你现在已经具备了页面过渡效果!这个简单的一行代码将在整个网站上应用交叉淡入淡出效果。你的网站现在就像是一个幻灯片。目前还不清楚 <meta> 标签是否是启用这个功能的最终解决方案,但我很高兴看到它能够正常工作。

添加个别元素过渡效果

你可能会有两个问题:

  • 如何创建比交叉淡入淡出更令人兴奋的效果?

  • 如何过渡特定的元素?

答案是:使用 CSS 中的命名视图过渡。给你想要从中过渡的元素(在 page1.html 上)和你想要过渡到的元素(在 page2.html 上)设置相同的独特的视图过渡名称。让我们以 Bootstrap 风格的 “Jumbotron” 为例说明。

<div class="jumbotron" style="view-transition-name: hero">
<!-- content goes here -->
<a href="/product.html">Buy Now</a>
</div>

在 product.html 页面上找到你希望元素转换成的目标元素,并给它设置相同的视图过渡名称(view-transition-name)。

<div class="product-header" style="view-transition-name: hero">
<!-- content goes here -->
</div>

完成!这样就可以在两个页面之间实现 "morph" 效果了。如果你不喜欢内联样式,也可以将其放入 CSS 文件中实现。

.jumbotron { view-transition-name: hero }
.product-header { view-transition-name: hero }

如果你想成为真正的冠军,还可以为那些容易晕车的人禁用 "morph" 效果。

@media not (prefers-reduced-motion: reduce) {
.jumbotron { view-transition-name: hero }
.product-header { view-transition-name: hero }
}

在我们深入了解如何创建自定义过渡效果之前,让我们先暂停一分钟,了解一下这个过程是如何运作的,并了解底层技术的一些限制...

这一切是如何运作的?

在幕后,浏览器正在对你要过渡的 DOM 元素的前后状态进行栅格化处理(即生成图像)。浏览器会计算出这两个快照之间的差异,并通过类似于苹果 Keynote 的 "Magic Morph" 功能、《终结者 2:审判日》中的液态金属 T-1000 或 20 世纪 80 年代的卡通系列《Turbo Teen》中的效果进行过渡。

如果你对之前提到的参考没有理解,那么我们可以使用一本受欢迎的儿童图书系列《Animorphs》作为类比。

这就是它的工作原理,我不会再回答其他问题了。根据经验,它似乎会协商前后状态的 X、Y 位置以及高度 / 宽度。然后,它将用栅格化图像(类似于过渡效果)热替换你的 DOM,调整高度 / 宽度的变换,平移位置,并在旧状态和新状态之间进行淡入淡出动画。基本但令人信服。

列表中的独特限制

目前,多页面应用(MPA)的视图过渡需要是唯一的!如果同一页上有两个具有相同过渡名称(例如 view-transition-name: post)的元素,浏览器会混淆并放弃视图过渡,而退而使用交叉淡入淡出效果。

幸运的是,如果你想要在列表视图和详细视图之间进行动画转换,并希望返回列表视图时能正常工作,可以通过在模板中添加唯一的 view-transition-name 来解决这个问题。以下是一个帖子列表的示例:

<div class="posts">
{% foreach post in posts %}
<a style="view-transition-name: post-{{ post.id }}" href="{{ post.url }}">{{ post.title }}</a>
{% endforeach %}
</div>

这个视图过渡在你的渲染的 HTML 中将具有 post-123 的名称。然后,在你的文章模板中,你将使用相同的 "slug" 将链接转换为文章标题。

<article>
<header style="view-transition-name: post-{{ post.id }}">
<h1>{{ post.title }}</h1>
</header>
...
</article>

现在你已经成功地绕过了系统,并能够按照你的期望进行过渡效果了。但需要注意的一个副作用是,这会在你的 Web Inspector 中创建许多伪元素(pseudo-elements)。

<!DOCTYPE html>
<html lang="en-us">
::view-transition-group(root)
::view-transition-group(post-123)
::view-transition-group(post-124)
... etc
::view-transition-image-pair(root)
::view-transition-image-pair(post-123)
::view-transition-image-pair(post-124)
... etc
::view-transition-old(root)
::view-transition-old(post-123)
::view-transition-old(post-124)
... etc
::view-transition-new(root)
::view-transition-new(post-123)
::view-transition-new(post-124)
... etc

我可以理解,这与 "DOM 节点过多" 的性能和调试问题可能有些相似。你可以自行决定如何处理,但我可能会对此持保守态度,并避免在大型列表上应用此技术。我希望能有一个更好的、不需要手动显式操作的 API 来处理列表到详细信息的过渡效果,但目前这种方法是可行的。

自定义你的视图过渡效果

如果 "morph" 过渡效果不符合你的需求,你可以使用 ::view-transition-old() 和 ::view-transition-new() 伪元素来控制你的命名视图过渡效果的旧(离开)状态和新(进入)状态。

/* Old stuff going out */
::view-transition-old(hero) {
animation: fade 0.2s linear forwards;
}

/* New stuff coming in */
::view-transition-new(hero) {
animation: fade 0.3s linear reverse;
}

@keyframes fade {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

这种技术使得对于即将进入和离开的内容具有控制权,虽然有些重复,但你可以对过渡元素应用自定义的 CSS 样式,修改其外观和行为。这样可以创建独特且个性化的视图过渡效果,超越默认的 "morph" 效果。

例如,你可以通过改变这些伪元素的不透明度、位置、背景颜色或其他 CSS 属性来创建不同类型的过渡效果,如淡入淡出、滑动或缩放效果。你使用的确切 CSS 属性和值将取决于你想要实现的具体过渡效果。

通过利用这些伪元素,你可以更加灵活地定制你的视图过渡效果,以符合你的设计偏好,并创建更具吸引力和视觉效果的效果。

通过尝试不同的 CSS 样式和属性,你可以实现所需的过渡效果,从而使你的网站焕然一新。

这种技术的潜力是无限的,你可以根据自己的需求和创意来进行更多的探索。准备好让惊人的动画擦除效果出现在你附近的网站上吧。

玩得开心,逐步优化

对于多页面视图过渡 API 的成功,相比之前提出的所有建议和解决方案,我认为最具有预示性的指标是,我实际上已经实现了这个。尽管动画多年来一直是我的拿手好戏,但我懒得尝试之前那一代的工具。

通过使用一个 <meta> 标签和一些 CSS 属性,轻松创建 60 FPS 的高质量页面过渡效果,这是一个游戏改变者,我期待更有创造力的人会用这项技术做出什么样的作品。我的脑海已经充满了各种想法。MPA 视图过渡的最好之处在于,在底层它只是普通的 "笨拙" 页面加载,而我们正在逐步优化我们的方式,实现智能、流畅的过渡效果,而且完全不需要 JavaScript。

我真希望其他浏览器也能加入进来。👀

关于本文
译者:@飘飘
作者:@Dave Rupert
原文:https://daverupert.com/2023/05/getting-started-view-transitions/

这期前端早读课
对你有帮助,帮” 
 “一下,
期待下一期,帮”
 在看” 一下 。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存