原生标签无法自适应缩放图片,必须用js动态重算coords;usemap与map的name需逐字节匹配;shape和coords格式须严格对应;响应式页面推荐改用svg替代。

原生 <area> 标签无法自适应缩放后的图片——它永远按原始像素尺寸(img.naturalWidth/img.naturalHeight)解析 coords,CSS 缩放后热区必然偏移。所谓“自适应”只能靠 JS 动态重算,没有纯 HTML/CSS 解法。
usemap 和 map 的 name 必须逐字节匹配
这是 90% 热区失效的起点。浏览器只做严格字符串比对,漏 #、大小写错、连字符/下划线混用,都会断连。
-
usemap="#product-map"✅ 必须对应<map name="product-map"></map> -
usemap="product-map"❌ 漏#,整个映射被忽略 -
usemap="#Product-Map"❌ 大小写不一致,断连 -
<map id="product-map"></map>❌usemap不认id,只认name
shape 和 coords 格式必须完全对应
coords 不是数字列表,而是由 shape 决定的结构化坐标。填错一位,热区可能缩成一个点、飞出画布,或覆盖整张图。
-
shape="rect"→coords="x1,y1,x2,y2":左上角 + 右下角,且必须满足x1 且 <code>y1 -
shape="circle"→coords="cx,cy,r":圆心横纵坐标 + 半径,r必须为正整数(不能是0或小数) -
shape="poly"→coords="x1,y1,x2,y2,x3,y3,...":顶点坐标成对出现,总数必须是偶数;首尾不自动闭合,Safari 等浏览器会静默跳过格式错误的poly - 别用
shape="default"做兜底:它会捕获所有未被其他<area>覆盖的点击,干扰调试
响应式页面必须用 JS 动态重算 coords
只要图片用了 max-width: 100%、width: 50% 或 object-fit,原始 coords 就立刻失准。缩放比 = img.offsetWidth / img.naturalWidth(宽高比不同时需分别计算)。
- 监听
img.addEventListener('load', updateCoords)和window.addEventListener('resize', updateCoords) -
updateCoords()中遍历所有<area>,把每个coords字符串拆解为数字数组,乘以缩放比后重新拼回字符串并赋值给area.coords - 移动端尤其关键:原始图 1200×800,
coords="0,0,100,100"缩到 375px 宽后仅约 31×21px,低于触控最小推荐尺寸 44×44px - 如果项目已重度响应式,直接改用 SVG 替代更省心:
<svg></svg>内部的<rect></rect>或<path></path>天然支持缩放,且无障碍支持完整
area 必须嵌套在 map 内,且 href 和 alt 不可省略
<area> 是空元素,不能自闭合(<area> 是错的),且必须是 <map></map> 的**直接子节点**。
- 放在
<div> 里、或写在 <code><map></map>外,所有浏览器都会忽略它 -
href必须为有效 URL:./page.html#id或javascript:void(0);纯#id不支持锚点跳转,且可能触发 404 请求 -
alt强制要求:哪怕只是空字符串alt="",否则不符合可访问性标准;屏幕阅读器只读alt,不读title或aria-label - 若
<img>在 Shadow DOM 里,外部<map></map>默认不可见——这是最容易被忽略的兼容性断点
真正难的不是写对第一版,而是图片缩放后热区还能精准命中。JS 重算逻辑看似简单,但缩放比取值、坐标四舍五入、多边形顶点顺序、移动端 touch 响应延迟,每个环节都可能让热区“差那么一像素”。建议上线前务必在真机上测试触控精度。











