最简单用title属性但功能有限;css+data-*可定制样式;js支持html内容和动态定位;现代css :has()零js但兼容性差;响应式下需校准定位。

用 title 属性最简单,但效果有限
直接给 <img> 加 title 属性,浏览器原生支持悬停显示文字气泡,比如:
@@##@@。但它没法控制样式、位置、延迟或动画,内容多了还会被截断,移动端基本不触发。适合内部管理页或快速原型,别用在正式产品里。
CSS + data-* 属性实现可定制的悬停提示
把信息存在 data-tooltip 里,用纯 CSS 控制显示逻辑,避免 JS 依赖。关键点是用 :hover 触发伪元素 ::after 渲染提示框:
@@##@@
img[data-tooltip] { position: relative; }<br>img[data-tooltip]::after {<br> content: attr(data-tooltip);<br> position: absolute;<br> top: -32px;<br> left: 50%;<br> transform: translateX(-50%);<br> background: #333;<br> color: #fff;<br> padding: 4px 8px;<br> border-radius: 4px;<br> font-size: 12px;<br> white-space: nowrap;<br> opacity: 0;<br> transition: opacity 0.2s;<br> z-index: 10;<br>}<br>img[data-tooltip]:hover::after { opacity: 1; }注意:必须加 position: relative 才能让 ::after 相对图片定位;z-index 要设,否则可能被其他元素遮住;white-space: nowrap 防止换行撑开提示框。JavaScript 动态插入更灵活的 tooltip 元素
当需要支持 HTML 内容、箭头、跟随鼠标、多图复用时,就得用 JS 创建真实 DOM 节点。核心思路是监听 mouseenter,计算位置,插入 <div class="tooltip">,再监听 <code>mouseleave 移除它:
document.querySelectorAll('img[data-tooltip-html]').forEach(img => {<br> img.addEventListener('mouseenter', e => {<br> const tooltip = document.createElement('div');<br> tooltip.className = 'tooltip';<br> tooltip.innerHTML = img.dataset.tooltipHtml;<br> tooltip.style.position = 'absolute';<br> tooltip.style.top = (e.pageY - 40) + 'px';<br> tooltip.style.left = (e.pageX + 10) + 'px';<br> document.body.appendChild(tooltip);<br> img._tooltip = tooltip;<br> });<br> img.addEventListener('mouseleave', () => {<br> if (img._tooltip) {<br> img._tooltip.remove();<br> img._tooltip = null;<br> }<br> });<br>});容易踩的坑:e.pageX/e.pageY 在滚动页面时要减去 window.scrollY 才准;多个图片共用 tooltip 时得清空上一个;没做防抖的话快速进出会创建一堆节点;移动端没有 hover,得额外处理 touchstart。用现代 CSS :has() 简化结构(需注意兼容性)
如果只支持 Chrome 105+、Safari 15.4+、Firefox 121+,可以用 :has() 把 tooltip 放在 img 同级,靠 CSS 控制显隐,不用 JS 绑事件:
<div class="img-container"> <br> @@##@@<br> <div class="tooltip">白头鹎,常见于南方,叫声清脆</div> <br> </div>
.img-container .tooltip { display: none; }<br>.img-container:has(img:hover) .tooltip {<br> display: block;<br> position: absolute;<br> top: -32px;<br> left: 50%;<br> transform: translateX(-50%);<br> background: #222;<br> color: #fff;<br> padding: 4px 8px;<br> border-radius: 3px;<br>}优势是零 JS、语义清晰;劣势是老浏览器完全不生效,且 :has() 不能用于 @media 或动画关键帧里。上线前务必查 caniuse.com/css-has 看目标用户覆盖率。真正麻烦的不是怎么显示,而是响应式场景下 tooltip 的定位校准——图片缩放、容器滚动、视口边界都会让提示框跑偏。建议优先用 CSS 方案,JS 方案务必加 resize 和 scroll 监听来重算位置,不然用户一拉滚动条,tooltip 就飘到屏幕外去了。













