弹出式窗口在网络上随处可见。您可以在菜单、切换提示和对话框中看到这些信息,它们可能以账号设置、披露信息微件和商品卡片预览的形式呈现。尽管这些组件非常常见,但在浏览器中构建它们仍然令人惊讶地繁琐。您需要添加脚本来管理焦点、打开和关闭状态、将可访问的钩子添加到组件中,以及键盘绑定以进入和退出该体验,而这一切都需要在您开始构建弹出式窗口的实用、独特的核心功能之前完成。
为解决此问题,我们将为浏览器推出一组用于构建弹出式窗口的新声明式 HTML API,从 Chromium 114 中的 popover
API 开始。
popover 属性
您可以使用 popover
属性和后续的一组功能,让浏览器处理所有复杂性,而不是自行管理。HTML 弹出式窗口支持:
- 提升到顶层。弹出式窗口将显示在网页其余部分上方的单独图层中,因此您无需费心调整 z-index。
- “轻触关闭”功能。点击弹出式窗口区域外部会关闭弹出式窗口并返回焦点。
- 默认的焦点管理。打开该弹出式窗口后,下一个标签页会在弹出式窗口中停止。
- 无障碍键盘绑定。按
esc
键会关闭弹出式窗口并返回焦点。 - 无障碍组件绑定。在语义上将 popover 元素连接到 popover 触发器。
现在,您无需使用 JavaScript 即可构建包含所有这些功能的弹出式窗口。基本弹出式窗口需要满足以下三个条件:
- 包含 popover 的元素上的
popover
属性。 - 包含 popover 的元素上的
id
。 - 在用于打开 popover 的元素上,具有 popover 的
id
值的popovertarget
。
<button popovertarget="my-popover"> Open Popover </button>
<div id="my-popover" popover>
<p>I am a popover with more information.</p>
</div>
现在,您已经拥有一个功能齐全的基本弹出式窗口。
此弹出式窗口可用于传达更多信息,也可以用作披露信息 widget。
默认值和替换项
默认情况下(如上一个代码段所示),使用 popovertarget
设置弹出式窗口意味着用于打开弹出式窗口的按钮或元素会切换其打开和关闭状态。不过,您也可以使用 popovertargetaction
创建显式弹出式窗口。这会替换默认的切换操作。popovertargetaction
选项包括:
popovertargetaction="show"
:显示弹出式窗口。
popovertargetaction="hide"
:隐藏 popover。
使用 popovertargetaction="hide"
,您可以在弹出式窗口中创建“关闭”按钮,如以下代码段所示:
<button popovertarget="my-popover" popovertargetaction="hide">
<span aria-hidden="true">❌</span>
<span class="sr-only">Close</span>
</button>
自动弹出式窗口与手动弹出式窗口
单独使用 popover
属性实际上是 popover="auto"
的快捷方式。打开后,默认的 popover
会强制关闭其他自动弹出式窗口(祖先弹出式窗口除外)。您可以通过轻触关闭或关闭按钮关闭此类弹出式窗口。
另一方面,设置 popover=manual
会创建另一种类型的弹出式窗口:手动弹出式窗口。这些元素不会强制关闭任何其他元素类型,也不会通过轻松关闭方式关闭。您必须通过计时器或显式关闭操作关闭这些窗口。适合 popover=manual
的窗格类型是指会显示和消失但不应影响页面其余部分的元素,例如消息通知。
如果您浏览上面的演示,就会发现点击弹出式窗口区域以外的区域不会使弹出式窗口轻触关闭。此外,如果有其他动作条打开,它们也不会关闭。
如需查看差异,请执行以下操作:
使用 popover=auto
的弹出式窗口:
- 打开时,强制关闭其他弹出式窗口。
- 可以轻关闭。
使用 popover=manual
的弹出式窗口:
- 请勿强制关闭任何其他元素类型。
- 请勿轻关闭。使用切换开关或关闭操作关闭它们。
设置 popover 的样式
到目前为止,您已经了解了 HTML 中的基本弹出式窗口。不过,popover
还提供了一些不错的样式设置功能。其中之一就是能够为 ::backdrop
设置样式。
在 auto
弹出式窗口中,此层位于顶层(弹出式窗口所在的位置)的正下方,而顶层位于页面其余部分的上方。在以下示例中,::backdrop
采用了半透明颜色:
#size-guide::backdrop {
background: rgb(190 190 190 / 50%);
}
popover
和 dialog
之间的区别
请务必注意,popover
属性本身不会提供语义。虽然您现在可以使用 popover="auto"
构建类似模态对话框的体验,但这两者之间存在一些关键区别:
使用 dialog.showModal
(模态对话框)打开的 dialog
元素是一种体验,需要用户明确互动才能关闭模态窗口。popover
支持轻触关闭。模态 dialog
则不会。模态对话框会使网页的其余部分处于不活跃状态。popover
则不会。
以上演示是一个具有弹出式窗格行为的语义对话框。这意味着页面的其余部分并非处于不活动状态,并且对话框弹出式窗口确实会采用轻触关闭行为。您可以使用以下代码构建具有弹出式窗口行为的此对话框:
<button popovertarget="candle-01">
Quick Shop
</button>
<dialog popover id="candle-01">
<button class="close-btn" popovertarget="candle-01" popovertargetaction="hide">...</button>
<div class="product-preview-container">
...
</div>
</dialog>
即将推出
互动式进入和退出
浏览器尚不支持为离散属性添加动画效果,包括在 display: none
之间添加动画效果,以及在顶层之间添加动画效果。不过,我们计划在紧随此版本之后发布的 Chromium 版本中提供这些功能。
借助对离散属性进行动画处理的功能,以及使用 :popover-open
和 @starting-style
,您将能够设置更改前和更改后的样式,以便在打开和关闭弹出式窗口时实现流畅的转换。我们来看一下前面的示例。为其添加进入和退出动画后,效果会更加流畅,并能提供更流畅的用户体验:
锚点定位
如果您想根据视口位置显示提醒、模态窗口或通知,弹出式窗口非常适合。不过,对于需要相对于其他元素定位的菜单、提示和其他元素,也可以使用弹出式窗口。这时,CSS 锚点就派上用场了。
以下放射状菜单演示使用 popover API 和 CSS 锚点定位,以确保 popover #menu-items
始终锚定到其切换触发器 #menu-toggle
按钮。
设置锚点与设置弹出式窗口类似:
<button id="menu-toggle" popovertarget="menu-items">
Open Menu
</button>
<ul id="menu-items" popover anchor="menu-toggle">
<li class="item">...</li>
<li class="item">...</li>
</ul>
您可以通过为锚点指定 id
(在此示例中为 #menu-toggle
)来设置锚点,然后使用 anchor="menu-toggle"
连接这两个元素。现在,您可以使用 anchor()
为 popover 设置样式。一个锚定到锚定切换开关基准线的中置弹出式菜单的样式可能如下所示:
#menu-items {
bottom: anchor(bottom);
left: anchor(center);
translate: -50% 0;
}
现在,您已经拥有一个功能齐全的悬停菜单,该菜单锚定到切换按钮,并具有悬停窗口的所有内置功能,无需 JavaScript!
总结
我们推出一系列新功能,旨在让 Web 应用的构建更易于管理,并默认更易于访问,而 popover API 是其中的第一步。期待您使用我们的弹出式窗口!