area标签的coords不随css缩放自动适配,必须用js动态重算:监听img.onload、resize事件,按scalex/scaley缩放各shape坐标,并确保usemap与map name严格匹配。

area 标签的 coords 坐标不随 CSS 缩放自动适配
这是最常被误判的起点:无论你给 <img> 加了 width: 50%、max-width: 100% 还是 transform: scale(0.75),<area> 的 coords 始终按图片原始像素尺寸(img.naturalWidth/img.naturalHeight)计算。CSS 只改渲染,不触发坐标重映射——浏览器不会“猜”你要缩放 coords。
必须用 JS 动态重算 coords 才能对齐缩放后的图片
纯 HTML/CSS 没有方案。响应式热区唯一可靠路径是监听关键事件,实时换算:
- 监听
img.onload获取naturalWidth和naturalHeight - 监听
window.resize和img.load(防止缓存跳过 onload) - 每次触发时计算缩放比:
scaleX = img.naturalWidth / img.offsetWidth,scaleY = img.naturalHeight / img.offsetHeight - 对每个
<area>的coords字符串做正则解析,按shape类型分别缩放:-
rect:四个数分别乘scaleX, scaleY, scaleX, scaleY -
circle:前两个坐标乘对应缩放比,半径乘Math.min(scaleX, scaleY)(保持圆形) -
poly:所有偶数索引(x 坐标)乘scaleX,奇数索引(y 坐标)乘scaleY
-
usemap 与 map name 必须逐字节匹配,否则 area 完全静默失效
常见错误不是坐标错,而是绑定失败——浏览器不报错也不提示:
-
<img usemap="#floor1">必须对应<map name="floor1"></map>,开头的#不可省略 - 大小写敏感:
usemap="#Floor1"≠<map name="floor1"></map> - 符号严格一致:连字符
-、下划线_、空格都不能混用 - 调试技巧:在 Chrome DevTools 中右键图片 → “检查”,看是否能高亮到对应
<map></map>;若不能,基本就是匹配失败
替代方案比硬调 coords 更可持续
当热区复杂、需多端适配或未来可能频繁修改时,<map>+<area></map> 的维护成本会陡增:
-
<svg></svg>是首选替代:用<path></path>描述区域,天然支持viewBox和 CSS 缩放,事件委托也更灵活 - 覆盖层方案(div + absolute 定位):用 JS 计算位置后动态生成带
background和border的<div>,再通过 CSS 控制悬停/激活样式——视觉可控,坐标逻辑和渲染解耦 <li>注意:不要尝试用 <code>transform: scale()或object-fit“修复” coords,它们对<area>无效
实际缩放比例计算容易忽略图片加载时机:
img.offsetWidth 在 onload 前可能为 0,必须等图片真实渲染完成再取值;而 naturalWidth 在 onload 后才稳定可用。











