coords必须基于naturalWidth/naturalHeight手动填写,缩放后截图量坐标必错;shape与coords格式须严格匹配;usemap与map name须完全一致;响应式下必须用JS动态重算coords。

coords 坐标必须按原图 naturalWidth/naturalHeight 手动填写
定位不准,90% 是因为你量坐标时用的是缩放后的图片,但 coords 只认原始像素尺寸。浏览器不会帮你换算,它只把你的数字原样映射到图片 intrinsic 尺寸上。
调试第一步:打开开发者工具,选中 <img> 元素,在 Elements 面板右下角查看 naturalWidth 和 naturalHeight(不是 offsetWidth)。你所有坐标值都得基于这两个数来量——比如原图是 1200×800,你在 PS 里量出按钮左上角是 (300, 150),那 coords="300,150,500,250" 才对,哪怕页面里这张图只显示为 300px 宽。
- 千万别用截图工具在浏览器里直接框选后读像素——此时图已缩放,坐标必然偏移
- 用 Chrome 的 “Capture area screenshot” 功能前,先临时加
style="width: auto; height: auto;"强制还原原始尺寸再截图 - 如果 CMS 或编辑器自动压缩了原图,
naturalWidth会变小,务必重新量一遍
shape 和 coords 格式不匹配导致热点“消失”
浏览器对 coords 字符串只做逗号切分和转整数,不校验逻辑。填错一位、多一位、空格多一个,热点就失效,且完全不报错。
常见翻车点:
立即学习“前端免费学习笔记(深入)”;
-
shape="rect"却写了 6 个数:coords="10,20,100,80,150,120"→ 浏览器取前 4 个,后两个丢弃,区域变小或错位 -
shape="poly"写了奇数个数(如 5 个)→ 最后一个坐标被忽略,多边形缺一条边 -
coords="100, 200, 150, 180"中有空格 → 第二个值截成"200",后面全丢,实际只剩"100,200" -
shape="circle"写了coords="400,300,0"或"400,300,-20"→ 半径非法,整个<area>被静默忽略
usemap 和 map name 不严格匹配等于没写
usemap 属性和 <map> 的 name 必须一字不差(包括大小写、#号),否则热区根本不会绑定。
检查要点:
-
<img usemap="#worldmap">对应的必须是<map name="worldmap">,不是id="worldmap",也不是name="WorldMap" -
<map>元素不能放在<template>、<noscript>或<head>里,必须在 DOM 中可查(可用document.querySelector('map[name="xxx"]')验证) - 动态插入
<map>时,确保它在<img>渲染完成之后才挂载,否则旧版 Safari 可能不识别 - 同一页面多个
<map>,name绝对不能重复,否则浏览器行为未定义
响应式下 coords 必须 JS 重算,CSS 无法修复
coords 不支持百分比、em、vw 等任何相对单位,规范明确只接受整数像素值。只要图片用了 max-width: 100%、width: 50% 或 Flex/Grid 拉伸,硬编码的 coords 就必然错位。
JS 重算不是可选项,是硬需求:
- 监听
img.addEventListener('load', update)和window.addEventListener('resize', update),缺一不可 - 每次执行前先判断
img.naturalWidth > 0,否则缩放比为NaN -
shape="circle"的半径r也必须缩放,不只是cx/cy - 移动端物理点击区建议 ≥ 44×44px,缩放后要校验最小尺寸,太小会导致误触或点不中
最易被忽略的一点:很多开发者以为“只要图宽高固定就不用 JS”,但只要用了 srcset 或 picture 切换不同分辨率原图,naturalWidth 就会变——这意味着你得在每次图片加载后都重算,而不是只 onload 一次。



















