滚动驱动的动画是网络上常见的用户体验模式。滚动驱动的动画与滚动容器的滚动位置相关联。这意味着,当您向上或向下滚动时,关联的动画会以直接响应的方式向前或向后拖动。例如,视差背景图片或阅读指示器会随着您滚动而移动,例如视差背景图片。
开发者通常使用 JavaScript 响应主线程上的滚动事件来创建滚动驱动的动画。因此,由于滚动事件是异步传递的,因此难以创建与滚动保持同步的高性能滚动驱动动画,并且往往因在主线程上导致卡顿。
不过,作为浏览器推出新的 CSS 和界面功能的一部分,您现在可以创建声明性滚动驱动的动画。借助滚动时间轴和视图时间轴这两个新概念(这些新概念与现有 Web Animations API (WAAPI) 和 CSS Animations API 集成,您现在只需几行代码,即可在主线程之外运行丝滑的滚动驱动的动画。在本案例研究中,您将了解 Tokopedia、redBus 和 Policybazaar 如何从这项新功能中获益。
Tokopedia
Tokopedia 将之前的自定义 JavaScript 实现替换为滚动驱动的动画,以优化其网页性能,并提升整个电子商务转化漏斗的整体浏览体验。
与使用传统 JavaScript 滚动事件相比,我们成功减少了高达 80% 的代码行,并观察到,滚动时的平均 CPU 使用率从 50% 降低至 2% - Andy Wihalim,Tokopedia 高级软件工程师
代码
以下实现使用 scroll()
函数设置用于控制 CSS 动画进度的匿名滚动进度时间轴。顶部粘性栏的可见性会根据定义的 animationRange
中的滚动位置而变化。
const toggleBar = keyframes({
to: { height: 48 },
});
export const cssWrapper = css({
position: 'fixed',
left: 0,
width: '100vw',
pointerEvents: 'none',
marginTop: 120,
height: 0,
overflow: 'hidden',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
animation: `${toggleBar} linear both`,
animationTimeline: 'scroll()',
animationRange: '20px 70px',
});
redBus
redBus 在其“待办事项”着陆页上针对移动设备和桌面设备提供不同的动画,并在转化漏斗的早期向所有用户展示。借助滚动驱动的动画,他们能够将这些自定义 JavaScript 实现替换为 CSS,从而达到相同的效果。
使用场景
包含图片显示(适用于移动设备)和封面流程(适用于桌面设备)的图库。
代码(移动设备)
在前面的示例中,Tokopedia 使用了匿名滚动进度时间轴。在以下代码中,redBus 使用命名的查看进度时间轴。动画会在元素最近的祖先滚动条(在本例中为照片库滚动条)内定义的 animation-range
内更改 <img>
元素的 opacity
和 clip-path
。
const reveal = keyframes`
from {
opacity: 0;
clip-path: inset(45% 20% 45% 20%);
}
to {
opacity: 1;
clip-path: inset(0% 0% 0% 0%);
}`
const CardImage = styled.div`
width: 100%;
height: 100%;
img {
border-top-left-radius: 0.75rem;
border-top-right-radius: 0.75rem;
height: 100%;
width: 100%;
object-fit: cover;
view-timeline-name: --revealing-image;
view-timeline-axis: block;
/* Attach animation, linked to the View Timeline */
animation: linear ${reveal} both;
animation-timeline: --revealing-image;
/* Tweak range when effect should run*/
animation-range: entry 25% cover 50%;
}
`;
我们非常高兴看到这项功能,因为它完美地融合了性能和更出色的体验,提高了我们的网页体验衡量因素以便进行搜索引擎优化 (SEO)。除此之外,极短的学习曲线使它成为每个电子商务网站必备的学习工具。我们还获得了其他团队的积极反馈和支持,将 SDA 用于更多用户体验历程。- Amit Kumar,redBus 高级工程经理。
政策集市
比较保险计划是指用户重复执行的关键操作,用于指导他们的决策制定过程。使用滚动驱动的动画,Policybazaar 会根据用户滚动表格而缩小低优先级元素的大小。这样可以带来流畅的滚动体验,同时提高可读性。
借助滚动驱动的动画,我们能够最大限度地扩大视口空间,以便用户比较方案,确保获得专注且清晰的阅读体验。- Rishabh Mehrotra,PolicyBazaar 人寿保险设计主管。
代码
与 Tokopedia 中的上一个示例类似,Policybazaar 使用 scroll()
函数设置匿名滚动进度时间轴,以控制 CSS 动画的进度。在这种情况下,系统会根据定义的 animation-range
中的滚动位置缩小字体大小并淡出标题。
@supports (animation-timeline: scroll()) {
.plan-comparison .inner-header {
animation: move-and-fade-header linear both;
}
.plan-comparison .left-side {
animation: shrink-name linear both;
}
.plan-comparison .inner-header, .plan-comparison .left-side {
animation-timeline: scroll();
animation-range: 0 150px;
}
}
@keyframes move-and-fade-header {
to {
translate: 0% -5%;
top:103px;
}
}
@keyframes shrink-name {
to {
font-size: 1.5rem;
}
}
滚动条驱动的动画是用户体验历程中的常见模式
所有精选电子商务公司都在包含卡片的网页上使用滚动条驱动的动画,为卡片添加动画效果以吸引用户的注意力。以下示例显示了用户体验历程不同阶段卡片上的滚动效果。这通常使用匿名视图进度时间轴来实现,该时间轴用于控制自定义 CSS 动画的进度,如以下 CSS 代码段所示。
@keyframes animate-in {
0% { opacity: 0; transform: translateY(10%); }
100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
0% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-10%); }
}
.flyin_animate {
animation: animate-in linear forwards;
animation-timeline: view();
animation-range: entry;
}
redBus(首页)
Policybazaar(商品详情页面)
Tokopedia(商品详情页面)
使用 Scroll 驱动的 Animations API 时的注意事项
对于不支持的浏览器,可以对滚动驱动的动画执行 polyfill 操作,例如使用滚动时间轴 polyfill。如果这样做,这将需要进行额外的测试,以确保它与您的框架良好运行,并且使用 polyfill 的浏览器不会遇到动画失败或卡顿的体验。
在使用滚动驱动的动画之前,您可以在 CSS 中使用 @supports
测试对动画时间轴的支持情况。例如:
@supports (animation-timeline: scroll()) {
}
资源
- 滚动驱动的动画演示
- 使用滚动驱动的动画,在滚动时为元素添加动画效果
- Codelab:CSS 中的滚动驱动型动画使用入门
- Chrome 扩展程序:滚动驱动的动画调试程序
- 滚动时间轴 Polyfill
- 要报告错误或新功能吗?我们期待收到您的反馈意见!
请浏览本系列中的其他文章,了解电子商务公司如何使用新的 CSS 和界面功能(如视图转换、弹出式窗口、容器查询和 has()
选择器)获益。