usemap 与 map 的 name 必须严格匹配(含 # 和大小写),coords 基于原始像素而非 css 渲染尺寸,area 必须含 href 和 alt 才具备语义与功能完整性。

usemap 和 name 必须严格匹配,漏掉 # 就完全失效
浏览器不会报错,但整个热区图点击无反应——这是最常被忽略的硬性规则。usemap 的值必须以 # 开头,且和 <map name="xxx"></map> 中的 name 完全一致(大小写、连字符、空格都不能差)。
常见错误现象:
-
<img usemap="product-map">→ 缺#,失效 -
<map name="Product-Map"></map>配usemap="#product-map"→ 大小写不一致,失效 -
<map></map>被包裹在<div style="display:none"> 里 → 不在文档流中,失效<p>调试建议:右键图片 → 「检查」,看是否能高亮到对应 <code><map></map>;如果没反应,先查这个。coords 坐标永远基于原始图片像素,不是 CSS 渲染尺寸
你用
img { width: 50%; height: auto; }缩放图片,<area coords="...">的数值依然要按图片文件本身的naturalWidth/naturalHeight填写。否则热区会严重偏移。例如原图是 1600×900,你在页面上用 CSS 显示为 400×225,那么
coords="0,0,200,150"看起来像左上角四分之一区域,实际点击位置仍按 1600×900 计算,结果点不到。使用场景:
- 设计稿给的是「缩放后坐标」?必须反向换算回原始尺寸:乘以
naturalWidth / renderedWidth - 用 PS 或在线工具(如 image-map.net)取点时,务必确认导出的是原始图尺寸下的坐标
- 临时加
border: 1px solid red到<img>,再用开发者工具「截图选区」比对坐标是否对齐
响应式下必须动态重映射 coords,不能靠 CSS 自适应
原生
<area>没有响应式能力,window.resize或图片加载完成时,必须手动更新每个<area coords>的值。实操建议:
- 记录图片原始宽高:
const naturalW = img.naturalWidth; const naturalH = img.naturalHeight; - 计算缩放比:
const scaleX = img.offsetWidth / naturalW; const scaleY = img.offsetHeight / naturalH; - 遍历所有
<area>,按 shape 类型分别处理坐标:矩形需缩放全部 4 个值,圆形缩放圆心 + 半径,多边形逐对缩放 x/y - 监听
img.addEventListener('load', updateCoords)和window.addEventListener('resize', updateCoords)
可直接用成熟方案节省时间:
rwdImageMaps(jQuery 插件)或手写轻量版逻辑——但别跳过这步,否则移动端几乎必错位。area 标签必须含 href 和 alt,否则语义与兼容性双崩
缺
href,点击无跳转行为;缺alt,不仅屏幕阅读器无法读出功能,旧版 Safari 会直接忽略该<area>。这不是可选建议,是底线。容易踩的坑:
- 只绑
onclick,删掉href→ 键盘用户按回车无效,右键「在新标签页打开」消失 - 写
href="#"又不event.preventDefault()→ 页面跳到顶部,体验断裂 - 用
href="javascript:void(0)"代替真实链接 → SEO 和可访问性受损,且部分浏览器限制执行
推荐做法:保留语义化
href(哪怕指向一个空锚点href="#speaker"),再用onclick做增强,并在回调里调用event.preventDefault()。真正难的不是写对第一版 map/area,而是让 coords 在各种设备缩放、DPR、CSS 覆盖、懒加载图片等组合场景下依然精准——这些细节不显眼,但一漏就导致热区大面积失灵。
- 设计稿给的是「缩放后坐标」?必须反向换算回原始尺寸:乘以











