惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
量子位
阮一峰的网络日志
阮一峰的网络日志
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hackread – Cybersecurity News, Data Breaches, AI and More
云风的 BLOG
云风的 BLOG
D
DataBreaches.Net
B
Blog
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
H
Help Net Security
The Cloudflare Blog
U
Unit 42

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
页面级可视动画View Transitions API初体验 « 张鑫旭-鑫空间...
张鑫旭,zhangxinxu · 2024-08-10 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11308
本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。

鸟儿走路听音乐动图 占位图

一、先从最简单的案例开始

本文介绍View Transitions API,可以实现类似Keynote里面神奇移动这样的动画效果,也即是浏览器自动识别场景1和场景2的不同,并让这个不同产生动画效果,特别适合复杂的页面级别的场景切换动画。

先从最简单的案例开始。

一、append图片淡出动画

传统方法实现页面插入一个图片并有动画效果,需要用到CSS3 animation定义,例如:

img {
  animate: fadeIn .2s both;
}
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
container.append(img);

而实现View Transitions API实现则是另外的风格,只需要JS代码,这样:

document.startViewTransition(() => {    
  container.append(img);
});

此时图片插入就有淡出效果了,如下视频所示(不动点击播放):

就是这么简单。

眼见为实,您可以狠狠地点击这里:startViewTransition实现图片插入淡入效果demo

二、若要改变动画时间和类型

虽然旧元素淡出,新元素淡入是最常用的动画效果,但是总会遇到需要自定义动画时长和类型的场景。

例如,我们希望图片淡入的时间是1s,或者希望图片append到页面中是放大效果,该如何处理呢?

此时,需要动画CSS属性了,几个专门为View Transitions API设计的CSS伪元素。

例如动画时长1s可以这么设置:

::view-transition-group(root) {
    animation-duration: 1s;
}

或者:

::view-transition-image-pair(root) {
    animation-duration: 1s;
}

或者:

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 1s;
}

上面突然出现的4个CSS伪元素估计很多人都看不懂,嗯……我想想,怎么讲才更好理解。

这么说吧,View动画的实现,本质上是新旧快照的diff然后动画。

所以,为了方便设置这些新旧快照的动画特性,就设计了若干全新的CSS伪元素,总共有5个,一起构成了一个伪元素树,其层级关系如下所示:

::view-transition
├─ ::view-transition-group(root)
│  └─ ::view-transition-image-pair(root)
│     ├─ ::view-transition-old(root)
│     └─ ::view-transition-new(root)
│ /* 等等... */

其中,root可以看成是根元素,这个名称是可以自定义的,后面会有说明

然后,动画执行最细枝末节的伪元素就是::view-transition-old::view-transition-new,因此这两个伪元素最为常用,至于其父级的几个伪元素,专门用在设置公共CSS属性的场景下,例如上面设置的动画时长。

动画类型设置

想要改变动画的类型,例如,从淡入效果变成放大效果,很多人会想到使用如下所示的代码:

::view-transition-new(root) {
    animation: scaleUp 1s;
}
@keyframes scaleUp {
  from {
    transform: scale(0.1);
  }
  to {
    transform: scale(1);
  }
}

然而,图片插入到页面后,出现的不是图片放大,而是整个视窗内容一起放大了,如下所示:

视窗整个放大示意

那该如何处理呢?这就需要用到view-transition-name这个CSS属性了。

补充于2026年2月26日

CSS页面过渡还支持一个名为:active-view-transition-type()的伪类函数。

当具有一种或多种特定类型的视图过渡正在进行(处于活动状态)时,:active-view-transition-type() CSS 伪类会匹配相应的元素,而一旦视图过渡完成,它将停止匹配。

html:active-view-transition-type(forwards, backwards) {
  /* ... */
}

以下是其关键作用:

  • 实现场景化动画: 配合 document.startViewTransition({ types: [...] }),开发者可以在 CSS 中利用 :active-view-transition-type(forwards):active-view-transition-type(backwards),让页面在“前进”和“后退”时分别展示向左或向右的滑入效果。
  • 精确控制元素过渡:该伪类函数可以匹配处于特定视图过渡状态的伪元素(如 ::view-transition-group),从而仅对特定的过渡操作设置 CSS 动画,而不会影响其他类型的操作。

这篇文章中有相关使用示意,这里不展开。

三、view-transition-name与局部动画

我们可以使用view-transition-name属性给任意的元素设置一个名称,此时,就可以将此名称作为参数,以约束::view-transition-old::view-transition-new的作用范围。

例如:

img {
    view-transition-name: wooo;
}
::view-transition-new(wooo) {
    animation: scaleUp 1s;
}
@keyframes scaleUp {
  from {
    transform: scale(0.1);
  }
  to {
    transform: scale(1);
  }
}

此时IMG插入到页面的时候,就可以看到放大效果了。截图示意:

放大截图示意

您可以狠狠地点击这里:::view-transition-new实现图片放大动画demo

需要注意的是,view-transition-name指定的名称一次只能适用于一个元素,否则会报错,例如下面的错误提示。

名称重复报错

因此,如果动画元素多个且重复,稳妥的方式是使用JS去赋予view-transition-name名称,例如:

img.style.viewTransitionName = 'wooo';
document.startViewTransition(() => {
    this.after(img);
    
    setTimeout(() => {
        img.style.viewTransitionName = '';    
    }, 1000);
});

这样,每一个append的图片都可以有放大显示的效果。

四、看似复杂的动画变得简单了

单个图片的动画并不能体现视区动画的强大,下面通过几个例子演示View Transitions API擅长且推荐做的事情。

案例1:倒序后列表的移动

在过去,在改变列表的顺序的时候,我一直希望可以有动画效果,这样用户才能够直观地看到变化的过程。

可实操下来,太复杂了,除非所有元素都是绝对定位,然后动态修改每一个元素的left,top值。

现在有了View Transitions API,事情就简单多了,因此视图动画他无需设置元素的具体的定位值,它是根据新旧快照前后的位置变化实现的动画效果。

所以事情就变成了:

  1. 给所有列表元素设置一个唯一的view-transition-name
  2. 执行startViewTransition()然后改变位置;

结束了,就这么两步,非常简单。

无论是DOM位置变化实现的倒序,还是CSS属性在视觉上实现的倒序都可以有动画效果。

如下GIF录屏所示:

倒序排序效果

眼见为实,您可以狠狠地点击这里:View Transition实现列表倒序动画demo

其中实现的关键要点就是给每个列表设置独立的视图动画名称,此时,浏览器会给每一个元素创建独立的动画组,执行的动画就不是页面级的,而是元素之间的。

案例2:DOM元素remove淡出

在过去,删除某个列表元素,执行DOM.remove()方法的时候,元素删除效果很生硬,“bang”地一下就没了,一不留神,都没注意刚才删除的是哪个列表。

jQuery里面有个fadeOut()方法很好用,淡出后元素隐藏。

但是现在都是数据驱动了,数据一变,哗,列表一变,硬邦邦的,fadeOut()效果想用都用不上。

现在有了View Transitions API,一切都简单了,数据变化(或DOM手动移除),startViewTransition一下,就可以看到元素移出加淡出的效果了,老卵了。

实现也非常简单:

第一步:列表元素设置唯一的view-transition-name
第二步:执行类似下面的JS代码。

document.startViewTransition(() => {
    dom.remove();
});

就有如下所示的删除动效了,简单高效效果还好。

移除删除动画效果示意

眼见为实,您可以狠狠地点击这里:View Transition实现DOM移除淡出动画demo

五、@view-transition与页面间动画

View Transitions API除了可以用在单页中,也可以用在多页面跳转场景中,实现步骤如下。

页面插入这么一段CSS语句:

@view-transition {
  navigation: auto;
}

然后设置页面之间切换的动画类型,例如:

/* 创建自定义动画 */
@keyframes move-out {
  from {
    transform: translateX(0%);
  }
  to {
    transform: translateX(-100%);
  }
}

@keyframes move-in {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0%);
  }
}

/* 给新旧快照应用动画效果 */
::view-transition-old(root) {
  animation: 0.4s ease-in both move-out;
}

::view-transition-new(root) {
  animation: 0.4s ease-in both move-in;
}

此时页面间切换,就会像单页页面一样,有滑来滑去的效果了。

页面滑来滑去示意

就是这么神奇,眼见为实:传统跳转页面变得单页一样滑来滑去demo

六、其他一些说明

View Transitions API还包括pagereveal和pageswap两个事件方法。

前者文档首次呈现时触发,无论是从网络加载新文档还是激活文档(从反向/正向缓存(bfcache)或预渲染器),后者在文档因导航而即将卸载时触发。

可以用来实现一些自定义行为。

好,暂时就说这么多吧,之后有其他新的东西再补充。

感谢阅读,欢迎。

尾部占位图,银月小可爱

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11308

(本篇完)