弹出式窗口在网络上随处可见。您可以在菜单、切换提示和对话框中看到它们,这些图标用于账号设置、披露信息微件和商品卡片预览等功能。尽管这些组件非常常见,但在浏览器中构建它们仍然令人惊讶地繁琐。为解决此问题,我们将为浏览器推出一组用于构建弹出式窗口的新声明式 HTML API,其中第一个是 Popover API。
弹出式窗口属于新推出的基准功能。
人们常常会将弹出式窗口与对话框混淆。不过,它们在行为方面存在一些重要区别。使用 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 中推出)相结合,以相对于其他元素定位弹出式窗口。例如,这对菜单和提示很有帮助。
资源
- 推出 popover API
- 弹出式窗口和对话框的区别
- 您想报告 bug 或请求新功能吗?我们期待收到您的反馈。
探索本系列中的其他文章,了解电子商务公司如何通过使用新的 CSS 和界面功能(例如滚动驱动型动画、弹出式窗口、容器查询和 has()
选择器)获益。