纯 CSS Tooltip 本质可行但不推荐:attr(data-tip) 仅限伪元素 content 使用,内容不可选、无障碍差,且 hover 在移动端失效;应优先用 title 兜底,复杂需求配合轻量 JS 实现。

用 :hover + attr() 做 Tooltip 本质可行,但有硬伤
纯 CSS 实现悬停显示说明文字(Tooltip),靠 :hover 触发、用 attr(data-tip) 提取内容,技术上能跑通,但实际项目中不推荐作为主力方案——因为内容不可选、不可聚焦、无障碍支持差,且 Safari 对 attr() 在非 content 中的支持长期受限。
attr(data-tip) 只能在 ::before/::after 的 content 里用
这是最常卡住的地方:你不能用 attr() 给 title 赋值,也不能用它设置 div 的文本内容。它只活在伪元素的 content 属性里,且必须搭配 data-* 属性。
常见错误现象:
– 写了 div { content: attr(data-tip); } → 无效(content 不是 display: none 元素的合法属性)
– 试图用 attr() 动态改 aria-label → 浏览器直接忽略
正确姿势:
立即学习“前端免费学习笔记(深入)”;
button[data-tip]::after {
content: attr(data-tip);
position: absolute;
background: #333;
color: #fff;
padding: 4px 8px;
font-size: 12px;
}
悬停区域小、交互容错低,移动端完全失效
CSS :hover 是桌面端“模拟指针”的产物,没有 hover 状态的设备(手机、平板、触控笔记本)根本不会触发。哪怕加了 @media (hover: hover) 判断,也无法补全点击展开逻辑。
使用场景要清醒:
– 仅用于内部工具、后台系统等强桌面依赖场景
– 不用于面向公众的响应式网站或需 WCAG 合规的页面
– 若必须兼顾移动端,得额外用 JS 监听 click 或 focus,此时纯 CSS 方案就退居为降级 fallback
容易踩的坑:
– Tooltip 元素紧贴触发元素,导致鼠标移过去瞬间消失(悬停断连)
– 没加 pointer-events: none 到 Tooltip 本身,导致移入 Tooltip 时 :hover 失效
– 忘记设 z-index,被父容器的 overflow: hidden 剪掉
真正轻量又可用的替代思路:最小化 JS + title 回退
如果只是想省事又不想埋坑,比纯 CSS 更稳的做法是:保留原生 title 属性做兜底,用几行 JS 控制一个轻量 span Tooltip,只在需要时挂载/卸载。
实操建议:
– 优先用 title:它自带可访问性、键盘焦点支持、移动端长按提示
– 若 UI 要求更高(圆角、箭头、动画),用 JS 创建 <div class="tooltip">,读取 dataset.tip 渲染,监听 mouseenter/focusin 显示,mouseleave/blur 隐藏
– 所有 tooltip 元素统一加 role="tooltip" 和 aria-hidden="true"(显示时改为 false)
性能提醒:避免给每个按钮都挂独立事件监听器,用事件委托更干净 —— 比如监听父容器的 mouseover,再用 event.target.matches('[data-tip]') 判断。
复杂点不在怎么写动画,而在于焦点管理、屏幕阅读器播报时机、以及 iOS Safari 上 focus 行为的不一致性。这些不是加个 :hover 就能绕开的。


















