这篇文档的定位

这是一篇持续更新的 Web API 笔记。Popover API 是第一个案例,后续可以继续补充其他 API(例如 View Transitions API、Clipboard API、Web Share API)。

Web API 是什么

可以把 Web API 理解为浏览器提供给页面脚本调用的一组能力。页面里的 JavaScript 通过这些接口访问浏览器功能,例如:

  • 读写 DOM(DOM API)
  • 网络请求(Fetch API)
  • 本地存储(Storage API)
  • 弹出层控制(Popover API)

所以你的理解是对的:页面里的 JavaScript 脚本可以调用这些 API 来实现功能。

Web API、Chrome API、标准的关系

不是所有“在 Chrome 里能用的 API”都等于通用 Web 标准,通常分三类:

  1. 标准 Web API:由标准组织和浏览器厂商协作制定,多个浏览器逐步实现(Popover API 属于这一类)。
  2. 实验性能力:可能还在提案/试验阶段,通常带实验标记或只在预览版本可用。
  3. 浏览器专有 API:某个浏览器或生态特有,不保证跨浏览器可用(常见于扩展平台能力)。

Web 标准通常由谁推进

  • WHATWG:维护 HTML、DOM 等活标准,很多 Web API 在这里落地。
  • W3C:维护和推进大量 Web 标准生态工作。
  • TC39:负责 JavaScript 语言本身(例如语法和内建对象),不直接定义 Popover 这类 DOM/UI API。
  • 浏览器厂商协作机制:通过提案、实现、互通测试(例如 Web Platform Tests)持续收敛行为一致性。

简单说:Popover API 不是“Chrome 私有接口”,而是 Web 标准体系中的 API;Chrome 只是较早实现的浏览器之一。

案例 1:Popover API

解决的问题

在 Popover API 之前,做一个弹出层(tooltip、下拉菜单、气泡卡片)通常要解决三个麻烦:

  1. 层级:弹出层要盖在页面其他内容之上,容易被父元素的 overflow: hidden 或 z-index 上下文卡住。
  2. 定位:弹出层要跟随触发它的元素,需要手动计算位置,或者引入第三方定位库。
  3. 关闭时机:点击弹出层外部、按 Esc、触发另一个弹出层,都要能自动关闭当前弹出层,通常要手写一堆事件监听。

Popover API 是浏览器原生方案,直接解决第一和第三个问题;配合 CSS Anchor Positioning 可以解决第二个问题。

基本用法

给元素加 popover 属性,就能让它渲染在浏览器的 top layer(顶层),不受父元素 overflow、z-index 影响,默认还自带点击外部关闭、按 Esc 关闭的行为:

<button popovertarget="my-popover">打开</button>

<div id="my-popover" popover>
  这是一个 popover
</div>

也可以用 JS 控制显示和隐藏:

const popover = document.getElementById('my-popover')
popover.showPopover()
popover.hidePopover()
popover.togglePopover()

popover 的三种取值

取值 行为
auto(默认) 点击外部、按 Esc、打开另一个 popover 都会自动关闭;同一时刻只能有一个 auto popover 打开
manual 完全由 JS 控制显示/隐藏,点击外部不会自动关闭
hint 用于提示类内容(如 tooltip),可以和一个 auto popover 同时显示

需要完全自控关闭时机(比如弹出层里有需要保留焦点的表单)时,用 manual。

默认样式是个坑

[popover] 元素有浏览器自带的 UA 样式,默认带黑色边框和内边距:

[popover] {
  position: fixed;
  inset: 0;
  margin: auto;
  border-width: initial;
  border-style: solid;
  border-color: initial; /* 效果上表现为一圈黑色实线边框 */
  padding: 0.25em;
  background-color: Canvas;
  color: CanvasText;
}

如果 popover 内部已经用 Tailwind、shadow-lg 之类的方式做了圆角卡片样式,这层默认边框和内边距会叠加在外面,视觉上像多了一圈突兀的黑框。解决办法很简单,自己覆盖掉:

[popover] {
  border: none;
  padding: 0;
  background: transparent;
}

另外一个容易被忽略的细节:如果 popover 内部有元素调用了 .focus()(比如打开时自动聚焦方便键盘操作),浏览器会给它加默认的 focus outline,看起来像第二圈蓝色边框。同样需要显式覆盖:

.popover-content:focus {
  outline: none;
}

配合 CSS Anchor Positioning 定位

Popover 常见的用法是跟随某个触发元素显示(比如鼠标悬停的单词旁边弹出翻译卡片)。这正是 CSS Anchor Positioning 要解决的问题:给触发元素声明一个锚点名字,popover 用 position-anchor 引用它,浏览器会自动处理相对定位,并在空间不够时按 position-try-fallbacks 翻转位置。

.anchor-el {
  anchor-name: --my-anchor;
}

.my-popover {
  position: fixed;
  position-anchor: --my-anchor;
  position-area: top;
  position-try-fallbacks: flip-block, flip-inline;
}

这样 popover 会默认显示在锚点上方,如果上方空间不够,自动翻转到下方,不用手写 getBoundingClientRect 计算坐标。

兼容性

Popover API 和 CSS Anchor Positioning 都是较新的标准。以 Popover API 为例,Chrome 从 114 开始支持(Edge 也是 114 起);Safari 和 Firefox 的支持进度不一致,生产环境使用前需要查一下当前版本的兼容情况,或者准备好降级方案(比如退回手写定位)。

后续 API 记录模板

后续可以按下面结构继续追加新 API 条目:

## 案例 N:API 名称

### 它解决的问题

### 基本用法

### 浏览器兼容性

### 注意事项与降级方案

参考