弹出式窗口随处可见。您可以在菜单、切换提示和对话框中看到这些选项,这些对话框用于帐号设置、披露声明 widget 和产品卡片预览等功能。尽管这些组件非常普遍,但在浏览器中构建它们仍然非常麻烦。为了解决此问题,我们将向浏览器推出一组新的声明式 HTML API,用于构建弹出式窗口,其中第一个是 Popover API。
弹出式窗口是新推出的基准 API 的一部分。
弹出式窗口通常与对话框相混淆。不过,它们的行为之间存在一些关键差异。使用 dialog.showModal
(模态对话框)打开的 dialog
元素是一种需要用户明确互动才能关闭模态的体验。popover
支持轻关闭。模态 dialog
则不会。模态对话框会使页面的其余部分闲置。popover
则不可以。详细了解差异。
本文是系列文章的一部分,该系列讨论了电子商务公司如何使用新的 CSS 和界面功能增强其网站。本文介绍了 Tokopedia 如何实现 Popover API 并从中受益。
Tokopedia
使用弹出式窗口属性最多可减少 React 中的 70% 代码行。模态窗口可由 HTML 原生控制,而无需在 JavaScript 中处理事件并使用
React.createPortal
将模态 DOM 移至document.body
的末尾。我们还可以使用@starting-style
为弹出式窗口的打开和关闭添加动画效果。- Andy Wihalim,Tokopedia 高级软件工程师。
Tokopedia 的商品详情页面 (PDP) 中包含了每件商品的多张商品图片。点击商品缩略图时,系统会打开一个模态窗口,以显示放大的图片。这是电子商务网站常用的模式。
代码
Tokopedia 使用 React 进行前端开发。在为此模态实现弹出式窗口 API 之前,他们使用了一个 DOM 模态和一个按钮。该按钮更改了 React 状态以打开模态窗口。借助 Popover API,他们可在元素中指定 popovertarget
属性,以通过与弹出式窗口元素的 ID 相同的值打开弹出式窗口。
使用此基本实现时,弹出式窗口可以正常工作,但会在无任何动画的情况下出现和消失。如需为弹出式窗口创建流畅的进入和退出动画,请使用 :popover-open
和 @starting-style
并允许显示离散属性的动画。在以下代码示例中,弹出式窗口使用 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',
'@starting-style': {
transform: 'scale(1)',
opacity: 1,
},
transform: 'scale(0.8)',
opacity: 0,
'&:popover-open': {
'@starting-style': {
transform: 'scale(0.8)',
opacity: 0,
},
transform: 'scale(1)',
opacity: 1,
},
});
为了迎合不支持 Popover API 的浏览器,Tokopedia 通过 oddbird 实现了 popover-polyfill(采用 gzip 压缩时,只有 3.2 KB)。他们对 polyfill 很满意,因为它运行良好且未导致性能下降。总体而言,他们在 React 中使用 Popover API 减少了高达 70% 的代码行数。
使用 Popover API 时的注意事项
Tokopedia 使用 React,该团队通过以下方式实现了代码拆分:为不使用弹出式窗口组件的页面卸载该组件,然后对弹出式窗口内容执行代码拆分。通过这种方式,他们减少了初始请求的大小。
考虑将弹出式窗口与 CSS 锚点定位结合使用(即将在 Chrome 中推出),以便相对于其他元素确定弹出式窗口的位置。例如,这对于菜单和提示很有帮助。
资源
- Popover API 简介
- 弹出式窗口和对话框之间的区别
- 要报告 bug 或请求新功能吗?我们期待收到您的反馈意见。
浏览本系列中的其他文章,探讨电子商务公司如何利用新的 CSS 和界面功能(如滚动驱动的动画、弹出式窗口、容器查询和 has()
选择器)获益。