弹出式窗口在网络上随处可见。您可以在菜单、切换提示和对话框中看到这些信息,它们可能以账号设置、披露信息微件和商品卡片预览的形式呈现。尽管这些组件非常普遍,但在浏览器中构建它们仍然极其麻烦。您需要添加脚本来管理焦点、打开和关闭状态、组件中的无障碍钩子、进入和退出体验的键盘绑定,这一切甚至在您开始构建弹出式窗口的实用、独特的核心功能之前就完成了。
为了解决此问题,我们将向浏览器推出一组用于构建弹出式窗口的新声明式 HTML API,从 Chromium 114 中的 popover
API 开始。
弹出式窗口属性
您可以使用 popover
属性和后续的一组功能,让浏览器处理所有复杂性,而不是自行管理。HTML 弹出式窗口支持:
- 提升到顶层。弹出式窗口会显示在网页其余部分的单独图层上,因此您不必在 Z-index 上四处移动。
- 轻关闭功能。点击弹出式窗口区域以外的位置,即可关闭弹出式窗口并返回焦点。
- 默认的焦点管理。打开该弹出式窗口后,下一个标签页会在弹出式窗口中停止。
- 无障碍键盘绑定。按
esc
键将关闭弹出式窗口并返回焦点。 - 可访问的组件绑定。在语义上将 popover 元素连接到 popover 触发器。
现在,您无需使用 JavaScript 即可构建具有所有这些功能的弹出式窗口。基本弹出式窗口需要满足以下三个条件:
- 包含 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
创建显式弹出式窗口。这会替换默认的 toggle 操作。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
的弹出式窗口:
- 请勿强制关闭任何其他元素类型。
- 请勿轻关闭。使用切换或关闭操作将其关闭。
设置弹出式窗口的样式
到目前为止,您已经了解了 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
之间和从 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()
设置弹出式窗口的样式。居中弹出窗口菜单(锚定在锚点切换按钮的基线)可以采用如下样式:
#menu-items {
bottom: anchor(bottom);
left: anchor(center);
translate: -50% 0;
}
现在,您已经拥有一个功能齐全的悬停菜单,它锚定到切换按钮,并具有悬停窗口的所有内置功能,无需 JavaScript!
总结
popover API 是一系列新功能中的第一步,通过这些新功能可以使构建 Web 应用在默认情况下更易于管理且更易于访问。期待您使用我们的弹出式窗口!