coords属性值是绝对像素,不响应式;图片宽度一变,热点就错位。必须用JS动态重算coords值,不能只靠CSS。

直接结论:coords 属性值是绝对像素,不响应式;图片宽度一变,热点就错位。必须用 JS 动态重算 coords 值,不能只靠 CSS。
coords 值为什么在图片缩放后失效
HTML <map> 里的 <area> 的 coords 是纯数字列表(如 "585,170,787,239"),单位是像素,且始终基于图片原始尺寸计算。当你把 <img> 设为 width: 100% 或 max-width: 100%,浏览器会拉伸/压缩图片,但 coords 不会自动按比例缩放——它还死守着原始宽高下的坐标点。
常见错误现象:
- 图片在小屏上被压缩,热点区域变小、偏右或消失
- 桌面端正常,移动端点击无反应(实际是点在了错位的空白区)
- 用 DevTools 查看
area元素,coords值没变,但视觉位置明显漂移
用 JavaScript 动态重算 coords 的关键步骤
核心思路:拿到图片原始宽度(naturalWidth),再除以当前显示宽度(offsetWidth),得出缩放比,再遍历每个 coords 数字乘上该比值。
立即学习“前端免费学习笔记(深入)”;
- 必须等图片加载完成再执行,否则
naturalWidth为 0 —— 用img.onload或img.complete && img.naturalWidth判断 - 不要用
window.innerWidth或getBoundingClientRect().width算缩放比,它们受父容器 padding/margin 干扰,应直接用img.offsetWidth / img.naturalWidth -
coords是字符串,需.split(',').map(Number)转数组,处理完再.join(',')拼回去 - 记得监听
resize事件并重新计算,但加防抖(如 100ms),避免频繁触发
简短示例:
const img = document.querySelector('img[usemap]');
const map = document.querySelector('map');
if (img && map) {
const updateCoords = () => {
const scale = img.offsetWidth / img.naturalWidth;
document.querySelectorAll('area').forEach(area => {
const coords = area.coords.split(',').map(n => Math.round(n * scale));
area.setAttribute('coords', coords.join(','));
});
};
img.addEventListener('load', updateCoords);
window.addEventListener('resize', debounce(updateCoords, 100));
}容易被忽略的兼容性与边界坑
不是所有 <area> 类型都适合简单缩放:
-
shape="circle"只有 3 个值(cx, cy, r),缩放时半径r要单独处理,不能和坐标混同计算 -
shape="poly"坐标点数为奇数,必须成对处理(x,y,x,y…),别漏掉最后一个 - Safari 对动态修改
coords的响应有延迟,建议修改后手动触发一次img.dispatchEvent(new Event('load'))强制刷新映射 - 如果图片用了
object-fit: cover,offsetWidth不等于实际渲染内容宽度,此时应改用getBoundingClientRect()获取图片内可见区域宽高,并按裁剪比例调整缩放逻辑
真正麻烦的不是算比例,而是你得确认每张图的 naturalWidth 是否可靠——比如从 base64 加载、或跨域图片未设 crossorigin,都可能导致该值读不到。这时候只能 fallback 到预存原始尺寸或服务端返回元数据。



















