Skip to content

HoverCard 悬停卡片 ​

指针停在触发元素(链接、头像、用户名)上一会儿,在旁边弹出一张预览卡片。 只有一句话的说明用 Tooltip;卡片里要放按钮、表单,或者需要点击才打开的,用 Popover。

基础用法

触发元素放进 trigger 插槽,指针停 700ms 打开卡片;移开 300ms 后关闭,这期间移进卡片就不关。键盘 Tab 到触发元素上同样打开。

<pt-hover-card>
  <a slot="trigger" href="#ptengine">@ptengine</a>
  <div style="display: flex; gap: 12px">
    <pt-avatar src="data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 80 80%27%3E%3Crect width=%2780%27 height=%2780%27 fill=%27%238fb3d9%27/%3E%3Ccircle cx=%2740%27 cy=%2731%27 r=%2715%27 fill=%27%23f1d3bd%27/%3E%3Cpath d=%27M12 80c2-18 14-28 28-28s26 10 28 28z%27 fill=%27%232f4b6e%27/%3E%3C/svg%3E" alt="Ptengine">P</pt-avatar>
    <div style="display: grid; gap: 4px">
      <strong>@ptengine</strong>
      <span>热图、A/B 测试与个性化,一站式体验优化。</span>
    </div>
  </div>
</pt-hover-card>
延时与方位

open-delay / close-delay 调整开关的延时(毫秒);placement / align 与 Popover 相同,放不下时翻到对面。

<pt-hover-card open-delay="200" close-delay="1000" placement="top" align="start">
  <a slot="trigger" href="#fast">很快打开,停留 1 秒</a>
  <div>open-delay=200、close-delay=1000,在触发元素上方行首对齐。</div>
</pt-hover-card>

只放补充信息,不放必需操作

悬停卡片是给看得见指针的用户的视觉增强(与 Radix HoverCard 同一语义):

  • 它不是对话框,触发元素上不写 aria-expanded,读屏用户拿不到卡片里的内容;
  • 触屏没有悬停,也没有等价的打开方式(组件忽略触屏的指针进出,点一下不会弹卡片)。

卡片里的信息在别处(例如点开触发链接后的详情页)必须同样拿得到。需要所有人都能操作的内容用 Popover。

打开与关闭 ​

操作结果
指针进入触发元素等 open-delay(默认 700ms)后打开
指针离开触发元素与卡片等 close-delay(默认 300ms)后关闭
关闭计时中指针移进卡片取消关闭;离开卡片后重新计时
键盘 Tab 聚焦触发元素(:focus-visible)等 open-delay 后打开
焦点离开触发元素与卡片立即关闭
Esc / 在触发元素与卡片之外按下指针立即关闭

鼠标点击触发元素带来的焦点不算键盘聚焦,不会打开卡片 —— 点一下链接只是去链接那里。 焦点从触发元素 Tab 进卡片里的链接时卡片保持打开;这时按 Esc 关闭,焦点回到触发元素。

位置 ​

placement(默认 bottom)、align(默认 center)、offset(默认 4px)与 Popover 相同: 放不下时翻到对面,入场动画随之从触发元素一侧滑入。卡片经 popover API 进顶层, 放在 overflow: hidden 的容器、表格单元格或带 transform 的祖先里都不会被裁切。

窄屏(≤640px)下不切底部抽屉:触屏本来打不开它,窄窗口的桌面浏览器里仍贴着触发元素更合理。

宽度默认 256px,用 CSS 变量 --pt-hover-card-width 改。

事件 ​

  • ptOpen:卡片每次真正渲染出来之后发,不论是交互打开还是外部写 open 打开的。
  • ptClose:只在用户交互关闭时发,detail.reason 是 pointer(指针离开)、blur(焦点离开)、 escape 或 outside。外部把 open 写成 false 不发。

外部写 open 立即开关,不走延时。与 Modal、Popover 共用一个层栈:Modal 里打开的悬停卡片, 第一下 Esc 只关卡片。

API ​

属性

属性Attribute类型默认值说明
alignalign"center" | "end" | "start"'center'交叉轴上的对齐:top / bottom 时 start 是行首一侧(RTL 下是右),left / right 时 start 是上
closeDelayclose-delaynumber300指针离开触发元素与卡片后多久关闭(毫秒);这期间移回来就不关
offsetoffsetnumber4卡片与触发元素之间的距离(px)
openopenbooleanfalse是否展开。悬停 / 聚焦打开、离开 / 失焦 / Esc / 点外面收起时组件自己改写;外部写入立即生效,不走延时
openDelayopen-delaynumber700指针进入(或键盘聚焦)触发元素后多久打开(毫秒)
placementplacement"bottom" | "left" | "right" | "top"'bottom'相对触发元素的方位。视口放不下时翻到对面,反射的属性仍是这里的首选值

事件

事件detail 类型说明
ptClose{ reason: PtHoverCardCloseReason; }用户交互收起后发,detail 说明是怎么收起的。外部把 open 写成 false 不发 **不冒泡**:弹层常互相嵌套(弹窗里的菜单、气泡卡片里的下拉),冒泡的话外层上的监听会收到内层的开关。
ptOpenvoid卡片渲染出来之后发(交互或属性打开都发) **不冒泡**:弹层常互相嵌套(弹窗里的菜单、气泡卡片里的下拉),冒泡的话外层上的监听会收到内层的开关。

插槽

名称说明
(默认)卡片内容
trigger触发元素,指针悬停或键盘聚焦时打开卡片

可定制的内部元素(::part())

part说明
base卡片面板(与 panel 同一元素)
panel卡片面板

CSS 变量

变量说明
--pt-hover-card-width卡片宽度,默认 256px

Apache-2.0 协议开源