Skip to content

Popover 气泡卡片 ​

点击 / 悬停 / 聚焦触发,可承载标题、正文与自定义内容的浮层面板。支持 12 向放置、双轴偏移、开合动画、portal、modal 化与嵌套浮层。

基础用法 ​

点击触发

点击打开

放置方向 ​

placement 支持 12 向:四基向 top / bottom / left / right 各配 -start / -end 交叉轴对齐(bottom-start 面板左缘对齐触发元素左缘,是最常见形态)。空间不足沿主轴翻转时对齐后缀保留(bottom-start → top-start),对齐后仍做视口夹取。

四个方向

上下左右

12 向放置(-start / -end)

bottom-startbottom-endright-starttop-end

触发方式 ​

trigger 控制触发方式:click(默认)/ hover / focus / contextmenu / manual,空格分隔可多选(如 "click hover")。hover 触发时 hover-delay / hover-hide-delay 控制开合防抖延时(默认 150 / 100ms,无延时 hover 会闪开闪关);悬停区域为触发元素 + 浮层面板(跨间隙移动不闪关)。manual 模式不绑定任何宿主事件,显隐完全由宿主 open 控制。

悬停触发

悬停打开点击或悬停右键打开

自定义开合延时

hover-delay=400hover-hide-delay=400

通用显隐延迟(open-delay / close-delay)

open-delay=400close-delay=400

触屏降级(coarse pointer 自动生效) ​

触屏设备(pointer: coarse,如手机 / 平板)没有稳定的 hover 语义:点按会同时合成 hover 与 click,若沿用桌面行为会出现「刚打开即关闭」。当 trigger 含 hover 时,触屏下 hover 通道自动停用、降级为点按切换——点按触发元素打开、再点按关闭、点按浮层外部关闭(外点关闭替代 hover-out);fine pointer(桌面鼠标)行为完全不变。与受控 open、long-press-delay 触屏长按兼容:长按打开后抬手不会误关(800ms 收尾守卫),下一次点按才切换。

触屏点按切换(触屏设备自动生效)

触屏点我

禁用 ​

disabled 禁用整个 popover:点击 / 悬停 / 聚焦 / 右键 / 按键触发均不响应,宿主降饱和(opacity .6)并同步 aria-disabled。禁用触发元素(如原生 disabled button)不会派发鼠标事件,可在外层包一层 span 再挂 popover(兼容方案)。

整体禁用

禁用(click)禁用(hover)

宽度定制 ​

width 控制面板宽度:数字(px)、"trigger"(与触发元素同宽)或任意 CSS 值(如 50%)。width="trigger" 适合「面板与触发控件等宽」的下拉选择形态。

宽度定制(width)

width="280"width="trigger"(220px)width="50%"same-width(180px)

布尔属性 same-width 是「面板与触发器严格等宽」的快捷通道(等效 width="trigger",但会同时内联归零 min-width——触发器比面板默认 min-width(200px)窄时也能严格等宽)。显式设置 width 属性时以 width 为准;移除 same-width 后宽度交还 CSS 兜底。

偏移与碰撞细调 ​

offset 双轴偏移:"主轴距离" 或 "主轴距离, 交叉轴偏移"(默认 8, 0)。碰撞细调:collision-padding 视口夹取边距(默认 4px);fallback-placements 自定义回退序列(请求放不下时按序列逐一尝试);hide-when-detached 锚点完全脱离视口时隐藏面板。

双轴偏移(offset)

offset="12, 20"offset="16"

碰撞细调(collision-padding / fallback-placements / hide-when-detached)

collision-padding=20fallback-placementshide-when-detached

初始焦点与键盘 ​

focus-on-open 打开时焦点移入面板内首个可聚焦元素;initial-focus 指定选择器精确聚焦(优先级更高,解析不到回落 focus-on-open)。trigger-keys 指定按键在触发元素聚焦时切换开合(空格分隔多键)。

指定初始焦点(initial-focus)

打开(焦点落在输入框)

打开后焦点直接进入下面的输入框:

按键打开(trigger-keys)

聚焦后按 Enter

Portal 挂载点 ​

append-to 把面板移到宿主容器之外(body 或选择器),避免被宿主容器的 overflow: hidden / clip 裁剪;定位基于视口坐标,移出后不受影响。面板移出 shadow 后点击面板内部仍不触发外部点击关闭。

Portal 挂载(append-to)

打开 Portal 面板

箭头与视口自动调整 ​

默认显示指向触发元素中心的箭头(锚点中心在面板指向边上的投影;视口边缘避让导致面板偏移时,箭头仍跟随锚点中心);arrow="false" 隐藏箭头。默认空间不足时自动沿主轴翻转并避让视口边缘;auto-adjust-overflow="false" 关闭自动调整,面板保持声明 placement(可能溢出视口)。

箭头显隐与指向

默认无箭头

箭头与角融合(arrow-merge)

bottom-start 融合对照

关闭自动调整

关闭自动调整

自定义内容 ​

自定义内容(slot=content)

打开面板
通过 slot="content" 可以放置任意自定义内容。

关闭按钮与声明式关层 ​

closable 在面板右上角显示关闭按钮(part="close"),点击关闭并还原焦点。内容里任意元素加 data-popover="close" 即声明式关层——点击它关闭 popover(适合「确定 / 知道了」类操作按钮)。

关闭按钮与声明式关层

closable面板内按钮关层
知道了

颜色变体 ​

color 语义色变体:primary / success / warning / danger——面板 tint 底 + 语义色描边(含箭头),全部由 token 派生(dark 主题自动适配)。

颜色变体(color)

primarysuccesswarningdanger

开合动画 ​

面板打开 / 关闭播放 fade + scale 动画,transform-origin 随放置方向感知(从「对着触发元素的那条边」向外展开,-start/-end 贴到对齐边)。prefers-reduced-motion 下自动停用动画。

开合动画(方向感知)

打开试试右侧展开

内容实时与自动关闭 ​

默认(无 fresh)关闭时内容冻结、打开时写入最新值;fresh 开启后关闭状态也持续同步内容(受控内容场景防闪烁)。auto-close 打开后超时自动关闭(引导提示 / onboarding 场景)。

fresh:关闭时内容持续更新

内容 → v1内容 → v2(关闭中)content: -打开查看内容

auto-close:超时自动关闭

打开(3s 后自动关)

嵌套浮层 ​

浮层内容里可以再打开子浮层(popover / tooltip):子浮层从父浮层内容触发,层级与定位自动正确;父层关闭时子层一并关闭;Esc 逐层关闭并逐层还原焦点。

嵌套浮层(卡片内再弹)

打开主卡片

父面板内再触发子浮层:

打开子卡片

虚拟触发 ​

virtual 模式没有真实锚点(同 tooltip):由宿主通过 virtual-x / virtual-y(视口坐标)或 virtual-anchor(锚点元素选择器)指定位置,适合图表、画布上的坐标提示;设置 open 控制显隐。虚拟模式下点击触发元素与外部点击都不改变状态,生命周期完全由宿主控制。

虚拟触发(画布坐标跟随)

移动鼠标查看坐标提示

虚拟触发(锚点坐标定位)

在 (160, 90) 打开关闭open: false

虚拟触发(锚点元素跟随)

modal 把 popover 变成模态浮层:全屏遮罩 + 焦点陷阱(Tab / Shift+Tab 在面板内循环,焦点逃逸拉回,仅最上层 modal 接管)+ 滚动锁(拦截 wheel / 滚动方向键,滚动条保持可见)+ aria-modal。点击遮罩关闭并还原焦点。

Modal 化(遮罩 + 焦点锁 + 滚动锁)

打开 Modal 面板

焦点被锁在面板内:

完成取消

无障碍关联与键盘 ​

触发元素自动同步 ARIA 关联:aria-haspopup="dialog" + aria-expanded(随开合)+ aria-controls(面板 id),屏幕阅读器可感知浮层状态。trigger-keys 默认 Enter Space——聚焦触发元素按 Enter / 空格即可开合(原生 button 上与合成 click 幂等,不会闪开闪关),可用属性覆盖为其他按键。

键盘开合(默认 Enter / Space)

聚焦后按 Enter / 空格

trap-focus 焦点陷阱 ​

trap-focus 把焦点陷阱从 modal 中独立出来:不显示遮罩、不锁滚动,但 Tab / Shift+Tab 在面板内循环不逃逸——适合表单浮层(背景仍可交互,焦点不出走)。modal 与 trap-focus 叠加幂等(陷阱只挂一份)。

trap-focus(表单浮层焦点不逃逸)

打开表单浮层
提交

关闭行为开关 ​

close-on-outside / close-on-escape(默认均为 true 保持现行为)分别控制「点击外部关闭」与「Esc 关闭」;oas-before-close 是可取消关闭事件(preventDefault() 阻止关闭),所有关闭入口(触发切换 / 外点 / Esc / 关闭按钮 / 声明式关层 / 遮罩 / auto-close / 面板内选择)都会先过它——detail.source 标注来源。

关闭开关 + 可取消关闭(oas-before-close)

外点不关Esc 不关拦截关闭演示

尺寸与样式变量 ​

size 尺寸档位:small / medium(默认)/ large——内边距、最小宽度与字号随之缩放(走 token)。面板样式可通过组件级 CSS 变量定制:--oas-popover-bg / --oas-popover-border / --oas-popover-shadow / --oas-popover-radius / --oas-popover-padding / --oas-popover-min-width(默认值回落全局 token,dark 主题自动跟随)。

尺寸档位(size)

smallmediumlarge

面板 CSS 变量定制(--oas-popover-*)

变量定制的面板

结构化插槽与说明 ​

slot="header" 接管整个头部(标题区让位);slot="footer" 渲染底部操作区(与正文以分隔线区隔);slot="description" 渲染补充说明并自动关联 aria-describedby(屏幕阅读器可朗读面板描述)。

header / footer / description 插槽

打开结构化面板
成员设置 Pro
正文内容区:与 header / footer / description 各自独立。

关闭后更改立即生效,无需保存。

取消确定

高度约束与面板内滚动 ​

available-height 把面板最大高度约束为主轴方向视口剩余空间;scrollable 开启面板内滚动(头部 / 底部固定、正文区滚动),长内容不再撑出视口。长列表场景两者常组合使用。

scrollable + available-height(长列表滚动)

打开通知(可滚动)

面板高度不超出视口剩余空间,正文区内部滚动:

通知 1通知 2通知 3通知 4通知 5通知 6通知 7通知 8通知 9通知 10

焦点归还与空态 ​

final-focus 指定关闭后焦点归还的目标元素(选择器;也可用 finalFocusEl property 传入元素,优先级更高);缺省归还触发元素。hide-empty 在面板无任何内容(无 title / content / 插槽内容)时保持隐藏——防止空白面板闪现。

final-focus(关闭后焦点到指定元素)

打开(✕ 关闭看焦点)

hide-empty(无内容不弹空白面板)

清空内容填入内容content: (空)无内容时点不开

滚动行为(sticky / close-on-scroll) ​

sticky 三档:partial(默认,滚动跟随重定位)/ always(锚点滚出视口后面板贴视口边缘保持可见)/ off(不跟随滚动)。close-on-scroll 则改为「滚动即关闭」——下拉选择类浮层在滚动时直接收起更符合直觉。

sticky=always(锚点滚出后面板贴边保持)

滚动下方区域看效果

↓ 滚动这里 ↓

close-on-scroll(滚动即关闭)

打开后滚动这里

右键光标定位与触屏长按 ​

trigger="contextmenu" 右键在光标处打开面板(不再锚定触发元素中心);触屏设备上按住长按同样在触点处打开(移动端没有右键),长按时长可用 long-press-delay 调整(ms,默认 500)。打开后滚动页面,面板回到触发元素侧跟随(光标点没有滚动语义)。

contextmenu 能力(主路径已默认内含):右键光标定位、触屏长按与 placement/size 断点简写属于独立能力包(子路径 @oas-ui/ui/feedback/popover/contextmenu,import 即注册);主路径 @oas-ui/ui/feedback/popover 已默认内含,无需显式引用(下方 demo 走全量入口同样已内含)。若改用纯核入口 @oas-ui/ui/feedback/popover/core 引入,则不含这些增强——此时 trigger="contextmenu" 仍支持基础右键触发打开面板(锚定触发元素,core 行为),但不定位光标、无长按与断点响应(控制台 dev 告警提示显式 import 能力包或换回主路径)。

contextmenu 光标定位(右键 / 触屏长按)

在这一带的任意位置右键

面板出现在右键光标处(触屏长按同样触发,长按时长由 long-press-delay 调整):

操作一操作二

面板内选择后自动关闭 ​

dismiss-on-select 开启后面板内任意点击(含插槽内容)视为完成选择并自动关闭——选项面板免写 data-popover="close"。关闭同样会经过 oas-before-close(可拦截)。

dismiss-on-select(选择即关)

选择一项试试
简体中文English日本語
open: false

内容销毁与懒挂载 ​

destroy-on-hide 关闭时卸载面板内容呈现(插槽节点脱离分配、属性文本清空),重新打开时再挂载——重内容(图表 / 大列表)浮层在关闭期间零渲染开销,等价懒挂载。宿主 light DOM 节点不会删除。

destroy-on-hide(关闭销毁、重开重建)

打开重内容面板

关闭后此内容被卸载(重开时重新挂载):

关闭后内容已卸载

断点响应与触发细调 ​

placement / size 支持断点简写(协议同 space/grid):"bottom md:right" = 基础值 + 空格分隔的 断点:值(sm=640 / md=768 / lg=1024 / xl=1280,移动优先 min-width)——窄屏在下方、≥768px 在右侧。断点响应属于 contextmenu 能力包(主路径默认内含,见上文「contextmenu 能力」;纯核 core 入口回落基础值)。trigger="mousedown" 按下即开(无需抬起,比 click 快一拍)。

placement 断点简写(拖动窗口宽度看切换)

bottom md:right

trigger=mousedown(按下即开)

mousedownclick(对照)

render-panel 纯面板渲染 ​

render-panel 面向宿主自组场景:popover 不绑定任何触发(一律按 manual 处理、不写触发元素 ARIA),配合 virtual-x / virtual-y 坐标或 append-to 由宿主完全接管摆放与显隐——比如自定义触发器、画布内嵌面板。

render-panel(宿主自组触发器)

宿主自己的按钮:打开纯面板关闭open: false

受控显示 ​

open 属性受控:外部按钮设置 / 移除 open 控制显隐(点击外部 / Esc 仍会关闭)。

受控显示(open 属性)

打开关闭open: false触发元素

API ​

oas-popover ​

属性 ​

属性说明类型默认值
append-toportal 挂载点:打开时面板移入目标容器(body 或 CSS 选择器),关闭移回宿主 shadow;适合面板被宿主容器裁剪(overflow)的场景string—
arrow是否显示箭头(默认 true;arrow="false" 隐藏,箭头元素与 ::part(arrow) 保留)stringtrue
arrow-merge箭头与面板角融合:直角三角与面板角共边融合——直角贴角点、直角边与面板两边共线(描边与面板描边共带续接),尖端正交指向锚点,对应角圆角归零;仅 -start/-end 位置生效,center placement 不触发boolean—
auto-adjust-overflow视口边缘自动翻转与避让(默认 true;"false" 关闭,保持声明 placement,可能溢出视口)stringtrue
auto-close打开后超时自动关闭(毫秒),如 auto-close="3000";未设置不自动关闭string—
available-height内容最大可用高度约束(视口剩余空间)boolean—
closable面板右上角显示关闭按钮(part="close"),点击关闭并还原焦点到触发元素boolean—
close-delay通用关闭延迟(毫秒,默认 0;非 hover 触发路径生效,hover 路径优先 hover-hide-delay)string—
close-on-escapeEsc 关闭(默认 true)——
close-on-outside点击外部关闭(默认 true)stringtrue
close-on-scroll滚动时关闭boolean—
collision-padding视口边缘夹取边距(px,默认 4),面板贴边避让时保留的间距string—
color颜色变体:primary / success / warning / danger(面板 tint 底 + 语义色描边,走 token 派生变量含 dark 变体);未设置或非法值保持默认中性面板string—
content正文文本string—
destroy-on-hide关闭后销毁面板内容呈现(宿主 light DOM 节点保留:改写 slot 名脱离分配并 hidden,属性文本清空);重新打开瞬间恢复挂载boolean—
disabled整体禁用:click / hover / focus / contextmenu / trigger-keys 触发均不响应,宿主降饱和并同步 aria-disabledboolean—
dismiss-on-select面板内容点击(命名 slot 内容 / 面板内部含关闭按钮)视为完成选择即关闭(可被 before-close 拦截);触发元素点击不触发(防点开即关)boolean—
fallback-placements自定义回退序列(逗号或空格分隔,如 "left, right"):请求 placement 放不下时按序列逐一尝试 fit,首个 fit 者胜出,全不 fit 取序列末位并夹取;未设置走默认主轴翻转string—
final-focus关闭后焦点归还目标(选择器)string—
focus-on-open打开时焦点移入面板内首个可聚焦元素boolean—
fresh关闭时也持续更新内容(默认关闭态冻结内容,打开时写入最新值;fresh 开启后关闭态同步写入)boolean—
hide-empty无内容时隐藏面板boolean—
hide-when-detached锚点完全脱离视口时隐藏面板(打开语义保留,避免孤悬屏外)boolean—
hover-delayhover 触发时打开防抖延时(毫秒,默认 150;未设置回落 open-delay)string—
hover-hide-delayhover 触发时关闭防抖延时(毫秒,默认 100;未设置回落 close-delay)string—
initial-focus打开时聚焦指定选择器元素(宿主 light DOM 优先,含 slot 内容;解析不到回落 focus-on-open),优先级高于 focus-on-openstring—
long-press-delay触屏长按触发延迟毫秒数(默认 500;仅 contextmenu 触发生效,属 contextmenu 能力包,能力语义见上文)——
modalmodal 化:全屏遮罩 + 焦点陷阱(Tab 面板内循环)+ 滚动锁 + aria-modal;点击遮罩关闭boolean—
offset双轴偏移:"主轴距离" 或 "主轴距离, 交叉轴偏移"(px,默认 8, 0),如 offset="12, 20"——
open受控显示(布尔属性,存在即显示)boolean—
open-delay通用打开延迟(毫秒,默认 0;非 hover 触发路径生效,hover 路径优先 hover-delay)string—
placement浮层位置(12 向:四基向 top/bottom/left/right 各配 -start/-end 交叉轴对齐)stringtop
render-panel纯面板渲染模式:无触发语义(一律按 manual 处理),定位回落 virtual 坐标/锚点,宿主可用 append-to 自行摆放boolean—
same-width面板宽度 = 触发器宽度(严格等宽;显式 width 优先)boolean—
scrollable面板内容超限滚动boolean—
size尺寸档stringmedium
sticky视口边缘贴住:partial(默认)/ always / off(关闭贴边跟随)stringpartial
title标题文本(渲染进可见标题区;读取后即从宿主移除,不残留原生悬浮提示;清空传空串);富内容用 slot="title"string—
trap-focus焦点陷阱独立开关(与 modal 遮罩解耦,表单浮层 Tab 不逃逸)boolean—
trigger触发方式:click(默认)/ hover / focus / contextmenu / manual,空格分隔可多选(如 "click hover")。含 hover 时触屏(coarse pointer)自动降级为点按切换:点按开、再点按/外点关,桌面 hover 行为不变stringclick
trigger-keys指定按键在触发元素聚焦时切换开合(空格分隔,如 "Enter Space";缺省即绑定 Enter Space)stringEnter Space
virtual虚拟触发模式(同 tooltip,不依赖锚点元素)boolean—
virtual-anchor虚拟锚点元素选择器(virtual-x/virtual-y 未设置时生效)——
virtual-x虚拟锚点 x(视口坐标,px)——
virtual-y虚拟锚点 y(视口坐标,px)——
width面板宽度:数字(px)/ "trigger"(与触发元素同宽)/ 任意 CSS 值(如 50%、240px);未设置保持默认string—

事件 ​

事件说明
oas-before-close关闭请求前派发(各关闭入口汇聚:trigger/outside/escape/close-btn/declarative/backdrop/auto/dismiss/scroll),cancelable,detail: { source },preventDefault 阻止关闭
oas-open-changeopen 状态变化,detail: { open }

插槽 ​

名称说明
默认面板主体内容
content面板内容(与默认插槽等价,具名便于显式指定)
description描述富内容插槽(aria-describedby 关联)
footer底部结构化插槽
header头部结构化插槽
title标题富内容插槽,有内容时覆盖 title 属性文案

CSS 变量 ​

CSS 变量默认值
--oas-glass-blurnone
--oas-glass-ringtransparent
--oas-origin-xcenter
--oas-origin-ycenter
--oas-popover-arrow-height12px
--oas-popover-arrow-radius0
--oas-popover-arrow-width12px
--oas-popover-bgvar(--oas-color-bg)
--oas-popover-bordervar(--oas-color-border)
--oas-popover-font-sizevar(--oas-font-size-md)
--oas-popover-min-width200px
--oas-popover-paddingvar(--oas-space-4)
--oas-popover-radiusvar(--oas-radius-md)
--oas-popover-shadowvar(--oas-shadow-md)

点击触发元素切换显隐,点击外部或按 Esc 关闭;role="dialog"。嵌套浮层:父关闭时级联关闭子层,Esc 逐层关闭并还原焦点到触发元素。

基于 MIT OR Apache-2.0 双许可发布