推出弹出式窗口 API

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

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

Popover 属性

浏览器支持

  • 114
  • 114
  • 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 则不可以。

以上演示是一个具有弹出式窗口行为的语义对话框。这意味着页面的其余部分不是 inerin 的,并且对话框弹出式窗口会获得轻度关闭行为。您可以使用以下代码构建具有弹出式窗口行为的此对话框:

<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 锚点定位,以确保弹出式窗口 #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 应用默认情况下更易于管理、更易于访问。期待看到大家使用弹出式窗口!

附加阅读材料