弹出式窗口在 Web 上随处可见。您可以在菜单、切换提示和对话框中看到它们,用于帐号设置、披露小部件和商品卡片预览等功能。尽管这些组件非常普遍,但在浏览器中构建它们仍然非常麻烦。为了解决这个问题,浏览器即将推出一套新的 声明式 HTML API,用于构建弹出式窗口,其中第一个是 Popover 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 状态以打开模态窗口。借助弹出式窗口 API,他们可以在打开弹出式窗口的元素中指定 popovertarget 属性,其值与弹出式窗口元素的 ID 相同。
通过这种基本实现,弹出式窗口可以正常工作,但显示和消失时没有任何动画效果。如需为弹出式窗口创建平滑的进入和退出动画,请使用 :popover-open 和 @starting-style,并允许离散属性的动画效果。
在以下代码示例中,弹出式窗口使用
transform: 'scale()'属性进行缩放。
此 代码示例 展示了 如何为弹出式窗口 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,
},
},
});
为了适应不支持弹出式窗口 API 的浏览器,Tokopedia 实现了 oddbird 的 弹出式窗口 polyfill, 该 polyfill 仅为 3.2 KB,并采用 gzip 压缩。他们对该 polyfill 非常满意,因为它运行良好,并且没有导致性能下降。总而言之,他们能够使用弹出式窗口 API 将 React 中的代码行数减少多达 70%。
使用 Popover API 时的注意事项
Tokopedia 使用 React,该团队通过卸载不使用弹出式窗口组件的页面的弹出式窗口组件,然后对弹出式窗口内容进行代码拆分,实现了代码拆分。这样,他们就减少了初始请求的大小。
考虑将弹出式窗口与 CSS 锚点定位 (即将推出 Chrome) 结合使用,以相对于其他元素定位弹出式窗口。例如,这对于菜单和工具提示非常有用。
资源
- 推出 Popover API
- 弹出式窗口与对话框的区别
- 您想报告 bug 或请求新功能吗?我们很想听取您的意见。
探索本系列中的其他文章,了解电子商务公司如何受益于使用新的 CSS 和界面功能,例如滚动条驱动的动画、弹出式窗口、容器查询和 has() 选择器。