滚动条驱动动画案例研究

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

滚动条驱动的动画是 Web 上常见的一种用户体验模式。滚动驱动的动画与滚动容器的滚动位置相关联。这意味着,当您向上或向下滚动时,关联的动画会直接响应并向前或向后播放。例如,视差背景图片或随滚动而移动的阅读指示器等效果。

开发者通常使用 JavaScript 来响应主线程上的滚动事件,从而创建滚动驱动的动画。由于滚动事件是异步传递的,因此很难创建与滚动同步的高性能滚动驱动动画,并且由于在主线程上运行,经常会导致卡顿。

不过,随着浏览器中新增 CSS 和界面功能,您现在可以创建声明式滚动驱动的动画。借助滚动时间轴和视图时间轴这两个与现有 Web Animations API (WAAPI)CSS Animations API 集成的新概念,您现在只需编写几行代码,即可实现流畅的滚动驱动动画,且这些动画可在主线程之外运行。在本案例研究中,了解 Tokopedia、redBus 和 Policybazaar 如何从这项新功能中获益。

Browser Support

  • Chrome: 115.
  • Edge: 115.
  • Firefox: behind a flag.
  • Safari: 26.

Source

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 在其活动着陆页上为移动设备和桌面设备设置了不同的动画,该着陆页会在转化漏斗的早期阶段向所有用户显示。借助滚动条驱动的动画,他们能够使用 CSS 替换这些自定义 JavaScript 实现,从而实现相同的效果。

使用场景

包含图片显示(适用于移动设备)和 Cover Flow(适用于桌面设备)的照片库。

用于在 redBus“活动”照片库中加载图片的滚动驱动动画图片显示效果。

代码(移动设备)

在前面的示例中,Tokopedia 使用了匿名滚动进度时间轴。在以下代码中,redBus 使用了命名视图进度时间轴。动画会更改元素最近的祖先滚动条(在本例中为照片库滚动条)内定义的 animation-range<img> 元素的 opacityclip-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

比较保险方案是用户在做出决策时反复采取的关键操作。Policybazaar 使用滚动驱动的动画,在用户滚动表格时缩小低优先级元素的大小。这样既能实现流畅的滚动体验,又能提高可读性。

借助滚动驱动的动画,我们能够最大限度地利用视口空间,让用户比较方案,确保他们获得专注且简洁的阅读体验。—Rishabh Mehrotra,PolicyBazaar 人寿保险业务部门设计主管

投资和人寿 LOB(业务线)中比较方案表格上的滚动条驱动的动画 animate-timeline

代码

与 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(首页)

在 redBus“待办事项”着陆页上加载商品卡片时,实现滚动驱动的动画飞入效果。

Policybazaar(商品列表页面)

在投资和生命 LOB(业务线)中,通过滚动驱动动画实现产品卡的淡入淡出效果。

Tokopedia(商品详情页面)

在滚动浏览列出的商品时,显示淡入淡出动画。

使用滚动条驱动的动画 API 时的注意事项

您可以为不支持滚动条驱动的动画的浏览器提供 Polyfill,例如使用 Scroll-timeline Polyfill。如果这样做,您需要进行额外的测试,以确保它能与您的框架很好地协同工作,并且使用 Polyfill 的浏览器不会遇到动画失败或卡顿的情况。

在 CSS 中,您可以使用 @supports 在使用滚动条驱动的动画之前测试对 animation-timeline 的支持。例如:

@supports (animation-timeline: scroll()) {  } 

资源

不妨浏览本系列中的其他文章,了解电子商务公司如何受益于使用新的 CSS 和界面功能,例如视图过渡、Popover、容器查询和 has() 选择器。