这篇文档的定位
这是一篇持续更新的 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 标准,通常分三类:
- 标准 Web API:由标准组织和浏览器厂商协作制定,多个浏览器逐步实现(Popover API 属于这一类)。
- 实验性能力:可能还在提案/试验阶段,通常带实验标记或只在预览版本可用。
- 浏览器专有 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、下拉菜单、气泡卡片)通常要解决三个麻烦:
- 层级:弹出层要盖在页面其他内容之上,容易被父元素的
overflow: hidden或z-index上下文卡住。 - 定位:弹出层要跟随触发它的元素,需要手动计算位置,或者引入第三方定位库。
- 关闭时机:点击弹出层外部、按
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 名称
### 它解决的问题
### 基本用法
### 浏览器兼容性
### 注意事项与降级方案