area标签不支持CSS样式,动态调整热区大小只能通过JS重写coords属性值;需用getComputedStyle读取CSS变量,按shape规则缩放坐标并转为整数字符串。

area 标签本身不支持 CSS 变量或任何 CSS 样式
直接用 style 或 CSS 类给 <area> 加 width、transform、--hotspot-size 等,完全无效。浏览器根本不解析 <area> 的样式——它没有渲染盒模型,不是可视元素,CSS 引擎直接跳过。你改了 style 属性,DOM 里看着有值,但热区坐标和响应范围丝毫不变。
想“动态改变热区大小”,只能重写 coords 属性值
热区大小由 coords 字符串里的数字决定,不是靠 CSS 缩放。所谓“动态”,本质是 JS 读取原始尺寸、计算缩放比、再按规则重赋值 area.coords。CSS 变量可作为中间媒介,但必须配合 JS 桥接:
-
--scale-x和--scale-y可设在<img>或<map>上,JS 用getComputedStyle()读取,再手动乘到每个 coords 数字上 - 矩形:
coords="x1,y1,x2,y2"→ 四个数分别乘对应方向缩放比 - 圆形:
coords="cx,cy,r"→ 前两个乘各自缩放比,半径建议用Math.min(scaleX, scaleY)避免压扁 - 多边形:
coords="x1,y1,x2,y2,..."→ 偶数位(x)乘scaleX,奇数位(y)乘scaleY - 别忘了:所有数值必须转为整数,且保留逗号分隔、无空格的字符串格式,例如
"120,90,25"
用 CSS 变量 + JS 的最小可行示例
HTML 中设变量:
<img src="map.png" usemap="#mymap" style="--scale-x: 0.5; --scale-y: 0.5;"> <map name="mymap"> <area shape="circle" coords="240,180,50" href="/a" alt="A"> </map>
JS 动态更新(需在图片加载后和窗口 resize 时调用):
立即学习“前端免费学习笔记(深入)”;
function updateHotspots() {
const img = document.querySelector('img[usemap]');
const map = document.querySelector('map[name="mymap"]');
const areas = map.querySelectorAll('area');
const cs = getComputedStyle(img);
const scaleX = parseFloat(cs.getPropertyValue('--scale-x')) || 1;
const scaleY = parseFloat(cs.getPropertyValue('--scale-y')) || 1;
<p>areas.forEach(area => {
const [cx, cy, r] = area.coords.split(',').map(Number);
area.coords = <code>${Math.round(cx * scaleX)},${Math.round(cy * scaleY)},${Math.round(r * Math.min(scaleX, scaleY))}</code>;
});
}真正该警惕的坑:coords 坐标永远绑定 naturalWidth/naturalHeight
哪怕你用 CSS 变量控制缩放,只要图片实际被 CSS 改变了显示尺寸(比如 width: 100%、max-width、object-fit),原始 coords 就已失效。变量只是帮你算得更快,不能绕过这个根本限制。最易忽略的是:高 DPR 屏幕(如 iPhone)下,offsetWidth 返回的是 CSS 像素,而 naturalWidth 是物理像素,差 2–3 倍——不处理 devicePixelRatio,移动端热区必偏移。



















