推出弹出式窗口 API

弹出式窗口在网络中随处可见。您可以在菜单、切换提示和对话框中查看这些信息,这些信息可以显示为账号设置、信息披露微件和产品卡片预览。尽管这些组件非常普遍,但在浏览器中构建它们仍然非常麻烦。您需要添加脚本来管理焦点、打开和关闭状态、组件中的无障碍钩子、进入和退出体验的键盘绑定,这一切甚至在您开始构建弹出式窗口的实用、独特核心功能之前就完成了。

为了解决此问题,我们将向浏览器推出一组用于构建弹出式窗口的新声明式 HTML API,从 Chromium 114 中的 popover API 开始。

弹出式窗口属性

浏览器支持

  • 114
  • 114
  • 125
  • 17

来源

您无需自行管理所有复杂工作,只需使用 popover 属性和后续功能集即可让浏览器处理。HTML 弹出式窗口支持:

  • 提升到顶层。弹出式窗口会显示在网页其余部分的单独图层上,因此您不必在 Z-index 上四处移动。
  • 轻关闭功能。点击弹出式窗口区域以外的位置,即可关闭弹出式窗口并返回焦点。
  • 默认焦点管理。打开弹出式窗口后,下一个标签页就会停止在弹出式窗口内。
  • 无障碍键盘绑定。esc 键将关闭弹出式窗口并返回焦点。
  • 可访问的组件绑定。从语义上将弹出式窗口元素连接到弹出式窗口触发器。

现在,您无需使用 JavaScript 即可构建具有所有这些功能的弹出式窗口。基本的弹出式窗口需要以下三项操作:

  • 包含弹出式窗口的元素上的 popover 属性。
  • 包含弹出式窗口的元素的 id
  • 一个 popovertarget,其值为打开弹出式窗口的元素上弹出的 id 的值。
<button popovertarget="my-popover"> Open Popover </button>

<div id="my-popover" popover>
  <p>I am a popover with more information.</p>
</div>

现在,您已经有一个功能完备的基本弹出式窗口了。

此弹出式窗口可用于传达更多信息,或用作披露声明微件。

默认值和替换项

默认情况下(例如在前面的代码段中),使用 popovertarget 设置弹出式窗口意味着打开弹出式窗口的按钮或元素会将其打开和关闭。不过,您也可以使用 popovertargetaction 创建显式弹出式窗口。这会替换默认的 toggle 操作。popovertargetaction选项包括:

popovertargetaction="show":显示弹出式窗口。 popovertargetaction="hide":隐藏弹出式窗口。

使用 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%);
}

popoverdialog 之间的区别

请务必注意,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 锚点定位来确保弹出式窗口 #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 应用在默认情况下更易于管理且更易于访问。很高兴看到你是如何使用弹出式窗口的!

附加阅读材料