Popover 案例研究

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

弹出式窗口在网络上随处可见。您可以在菜单、切换提示和对话框中看到它们,这些图标用于账号设置、披露信息微件和商品卡片预览等功能。尽管这些组件非常常见,但在浏览器中构建它们仍然令人惊讶地繁琐。为解决此问题,我们将为浏览器推出一组用于构建弹出式窗口的新声明式 HTML API,其中第一个是 Popover API

弹出式窗口属于新推出的基准功能

浏览器支持

  • Chrome:114.
  • Edge:114。
  • Firefox:125.
  • Safari:17.

来源

人们常常会将弹出式窗口与对话框混淆。不过,它们在行为方面存在一些重要区别。使用 dialog.showModal(模态对话框)打开的 dialog 元素是一种体验,需要用户明确互动才能关闭模态窗口。popover 支持轻触关闭。模态 dialog 则不会。模态对话框会使网页的其余部分处于惰性状态。popover 则不会。详细了解差异

本文是系列文章中的一篇,介绍了电子商务公司如何使用新的 CSS 和界面功能增强其网站。在本文中,了解 Tokopedia 如何实现 Popover API 并从中受益。

Tokopedia

使用 popover 属性可在 React 中最多减少 70% 的代码行数。模态窗口可以由 HTML 原生控制,而无需在 JavaScript 中进行事件处理,也不需要使用 React.createPortal 将模态 DOM 移至 document.body 的末尾。我们还可以使用 @starting-style 为弹出式窗口的打开和关闭添加动画效果。- Andy Wihalim,Tokopedia 高级软件工程师

Tokopedia 的商品详情页面 (PDP) 包含每件商品的多张商品图片。点击商品缩略图后,系统会打开一个模态窗口来显示放大的图片。这是电子商务网站中常用的一种模式。

代码

Tokopedia 使用 React 进行前端开发。在为此模态窗口实现 popover API 之前,他们使用的是 DOM 模态窗口和按钮。该按钮更改了 React 状态,以打开模态窗口。使用 popover API,他们在用于打开 popover 的元素中指定 popovertarget 属性,其值与 popover 元素的 ID 相同。

采用此基本实现后,弹出式窗口可以正常运行,但在显示和消失时没有任何动画效果。如需为弹出式窗口创建流畅的进入和退出动画,请使用 :popover-open@starting-style,并允许对离散属性进行动画处理。在以下代码示例中,该 popover 使用 transform: 'scale()' 属性进行放大和缩小。

代码示例展示了如何为 popover API 实现进入和退出动画。

<Thumbnail popovertarget="medialightbox" />
<MediaLightbox popover id="medialightbox" />
export const cssModalWrapper = css({
  background: NN0,
  border: 'none',
  borderRadius: '.625rem',
  width: 1024,
  padding: 24,

  '&::backdrop': {
    opacity: 0,
    transitionProperty: 'opacity, display',
    transition: '.25s ease-out',
    transitionBehavior: 'allow-discrete',
  },

  transitionProperty: 'transform, opacity, display',
  transition: '.25s ease-out',
  transitionBehavior: 'allow-discrete',

  transform: 'scale(0.8)',
  opacity: 0,
  '@starting-style': {
    transform: 'scale(1)',
    opacity: 1,
  },

  '&:popover-open': {
    transform: 'scale(1)',
    opacity: 1,
    '@starting-style': {
      transform: 'scale(0.8)',
      opacity: 0,
    },
  },
});

为了适应不支持 popover API 的浏览器,Tokopedia 实现了 oddbird 的 popover-polyfill,该 polyfill 经过 gzip 压缩后只有 3.2 KB。他们对该 polyfill 感到满意,因为它运行良好且不会导致性能回归。总体而言,他们能够使用 popover API 在 React 中最多减少 70% 的代码行。

使用 Popover API 时的注意事项

Tokopedia 使用 React,该团队通过为不使用该组件的页面卸载 popover 组件,然后为 popover 内容进行代码拆分,实现了代码拆分。这样,他们就缩减了初始请求的大小。

不妨考虑将弹出式窗口与 CSS 锚点定位(即将在 Chrome 中推出)相结合,以相对于其他元素定位弹出式窗口。例如,这对菜单和提示很有帮助。

资源

探索本系列中的其他文章,了解电子商务公司如何通过使用新的 CSS 和界面功能(例如滚动驱动型动画、弹出式窗口、容器查询和 has() 选择器)获益。