悬停或键盘聚焦时浮出的一句解释:术语(「晕眩」「无敌」)、缩写、图标按钮的名字、技力回复方式。反转底(暗主题白底黑字、亮主题黑底白字)、直角、12px 字。
两种实现
纯 CSS:data-ak-tip | Vue:AkTooltip | |
|---|---|---|
| 写法 | 任意元素加 data-ak-tip="文字"(气泡是 ::after) | #trigger 放触发元素,默认插槽放内容 |
| 内容 | 属性里的一句字符串 | 任意内容(加粗、换行、链接) |
| 方向 | 只在上方 | placement:上 / 下 / 左 / 右,上下可左 / 右缘对齐 |
| 触发 | 悬停 + 触发元素自己 :focus-visible(不可聚焦的元素由皮肤脚本补 tabindex="0") | 悬停 + 聚焦(默认)/ 只聚焦 / 点击 / 手动(v-model) |
| 读屏 | 皮肤脚本补 aria-describedby,指向页面里一个隐藏的描述节点(提示与元素自身名称相同时跳过,如道具图 alt = 道具名);无 JS 时不关联 | 触发元素 aria-describedby 指向 role="tooltip";Esc 收起 |
| 用在 | MW 模板、Lua 输出、不需要 JS 的地方;AkItem 的 tip 也是它 | 小部件里需要上面任何一项时 |
两者外观相同(.ak-tooltip 与 [data-ak-tip]::after 用同一组令牌)。一两句话的长解释:纯 CSS 版加 .ak-tip--wide(允许折行、最宽 280);Vue 版自动在 280px 处折行。
给开关、复选框这类「外层 <label> + 原生控件」的组件加提示,data-ak-tip 直接写在组件上:AkSwitch / AkCheckbox / AkRadio / AkInputNumber / AkSearch 把它落到外层(原生 <input> 上画不出 ::after),悬停名称文字也出提示,键盘聚焦到里面的控件时由 :has(:focus-visible) 显示。不要为了提示再包一层 <span data-ak-tip>:行内的 span 里控件按基线排,在 align-items: center 的一行里会比旁边没包的同类高几像素。
纯 CSS 版的气泡闲置时收成 0 宽(max-width: 0 + overflow: hidden),不只是透明——透明的气泡仍占布局,靠近右缘的长提示会把手机页面撑出横向滚动、整页跟着缩小(干员页 130 枚提示就是这么发现的,见贡献一个组件 · 命名与约定)。
基本用法
写法同 Naive UI 的 n-tooltip。触发元素取 #trigger 里的第一个元素 / 组件;是 <span class="ak-term"> 这种不可聚焦的元素时自动补 tabindex="0",键盘用户也能看到。trigger="click" 改成点击开合(点外面 / Esc 收起)。
方向
placement:top(默认)· bottom · left · right,间距 6px,同纯 CSS 版;top-start / bottom-end 这类是与触发元素左 / 右缘对齐(同 Naive)。不自动翻转(不引定位库):贴着视口边缘的触发元素自己选方向 / 对齐。下面用 v-model 让四个提示常显。
弹出卡片 Popover
AkPopover(同 Naive 的 n-popover):白底卡片、顶边 2px 主色条、最宽 360,能放标题(title / #header)、段落、链接、道具。默认点击开合——里面常有可点的东西,悬停弹出的卡片键盘用户够不着;只是富文本解释时可以 trigger="hover"。点外面 / Esc 收起,焦点在卡片里时还给触发元素。
可访问性
- 提示里只放补充说明:不要把完成任务必需的信息只写在提示里(触屏没有悬停)。
- 触发元素必须可聚焦;
AkTooltip对原生不可聚焦的元素自动补tabindex="0",组件(如AkButton)假定自己渲染可聚焦元素。 - 悬停出现的提示可以移进去(离开后
duration毫秒才消失),Esc随时收起——满足 WCAG 1.4.13。 - 点击打开的 Popover 是非模态对话框:触发元素
aria-haspopup="dialog"+aria-expanded+aria-controls,卡片role="dialog"、有标题时aria-labelledby指向标题;悬停打开的等同富文本提示(aria-describedby)。
Vue API
AkTooltip
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
placement | "bottom""top""top-start""top-end""bottom-start""bottom-end""left""right" | "top" | 出现在触发元素的哪一边:top(默认)· bottom · left · right;-start / -end 与触发元素左 / 右缘对齐。不自动翻转,贴边的触发元素自己选 |
trigger | "click""hover""focus""manual" | "hover" | 触发方式:hover 悬停 + 键盘聚焦(默认)· focus 只看聚焦 · click 点击开合 · manual 只由 v-model 控制 |
delay | number | 100 | 悬停多久后出现(ms) |
duration | number | 100 | 移开多久后消失(ms);这段时间里鼠标能移进提示里 |
disabled | boolean | false | 禁用:不再出现 |
modelValue | boolean | false | 是否显示;不绑定时由 trigger 决定 |
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | [value: boolean] |
| 插槽 | 说明 |
|---|---|
trigger | 触发元素:取第一个元素 / 组件;只有文字时自动包一层 <span>,不可聚焦的元素自动补 tabindex="0" |
default | 提示内容(短句;较长的解释会在 280px 处折行) |
AkPopover
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
title | string | — | 标题(粗体一行);也可以用 #header 插槽 |
placement | "bottom""top""top-start""top-end""bottom-start""bottom-end""left""right" | "bottom" | 出现在触发元素的哪一边:bottom(默认)· top · left · right;-start / -end 与触发元素左 / 右缘对齐。不自动翻转,贴边的触发元素自己选 |
trigger | "click""hover""focus""manual" | "click" | 触发方式:click 点击开合(默认)· hover 悬停 + 键盘聚焦 · focus 只看聚焦 · manual 只由 v-model 控制 |
delay | number | 100 | hover 模式:悬停多久后出现(ms) |
duration | number | 100 | hover 模式:移开多久后消失(ms);这段时间里鼠标能移进卡片里 |
disabled | boolean | false | 禁用:不再弹出 |
modelValue | boolean | false | 是否显示;不绑定时由 trigger 决定 |
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | [value: boolean] |
| 插槽 | 说明 |
|---|---|
trigger | 触发元素:取第一个元素 / 组件;只有文字时自动包一层 <span>,不可聚焦的元素自动补 tabindex="0" |
default | 卡片正文 |
header | 标题行(代替 title) |
CSS 实现
.ak-term 是术语的虚线下划线(悬停淡青底),data-ak-tip 与 AkTooltip 都可以配它。.ak-tip-anchor 与 .ak-tooltip--* / .ak-popover--* 方向修饰是给 Vue 版定位用的:外层相对定位,气泡贴在一边。外层是 inline-flex,大小就是触发元素的大小——包着开关、复选框、图片这类基线在底边的元素时,不会像 inline-block 那样在下面留出文字下沉的空间、把它顶高几像素;触发元素是术语(.ak-term / .ak-rt-term)时保持 inline-block,虚线下划线的位置不变。
| 块 | 元素 __ | 修饰 -- |
|---|
