coords缩放后点不准是因为它绑定图片naturalWidth/Height而非CSS渲染尺寸,浏览器不自动重算;需JS监听load/resize,用offset/natural比值动态缩放坐标,或改用viewBox匹配原图尺寸的SVG方案。

area coords 为什么缩放后就点不准
因为 coords 永远绑定图片的 naturalWidth 和 naturalHeight,不是你看到的 CSS 渲染尺寸。比如原图是 1200×800,coords="100,100,200,200" 表示原始图上一个 100×100 像素的矩形;当用 max-width: 100% 缩到 375px 宽时,这个区域在屏幕上实际只有约 31×21px,远小于触控最小推荐尺寸 44×44px,且位置完全偏移。
这不是 bug,是 HTML 规范设计如此——浏览器从不自动重映射 coords,哪怕你加了 transform: scale() 或 object-fit: contain,也毫无作用。
怎么用 JS 动态重算 coords 缩放值
核心逻辑是:拿到原始宽高、当前渲染宽高,算出两个方向的缩放比,再把每个 coords 数值按坐标类型(x 或 y)分别乘以对应比例。
-
img.naturalWidth和img.naturalHeight是唯一可信的原始尺寸来源(不能用width/height属性,可能没设) - 用
img.offsetWidth/img.offsetHeight获取当前渲染尺寸(别用clientWidth,它受 padding 影响) - 缩放比必须分开计算:
scaleX = offsetWidth / naturalWidth,scaleY = offsetHeight / naturalHeight - 遍历所有
area元素,对coords字符串做split(',')→map(Number)→ 按索引奇偶判断是 x 还是 y → 分别缩放 →join(',')后重新赋值给area.coords
关键监听事件:图片 load(防止 natural 尺寸为 0) + window.resize(响应式布局变化)。
立即学习“前端免费学习笔记(深入)”;
poly 区域缩放要注意顶点顺序和闭合
shape="poly" 的 coords 是成对出现的顶点,总数必须为偶数。缩放时不能简单整体乘比例——必须确保每对 (x, y) 都被正确处理,否则多边形会扭曲或翻转。
常见陷阱:
- 导出坐标时带空格或换行(如 Figma 插件输出),
split(',')会得到["100 ", " 200", ...],Number("100 ") === 100虽然能转,但建议先trim() - 顶点顺序混乱(比如顺时针 vs 逆时针混用),缩放后交叉更明显,Firefox 在顶点数 > 50 时悬停检测明显变慢
- 误以为首尾需手动重复闭合 —— 实际上浏览器会自动连线,重复反而导致冗余点、坐标数变奇数而解析失败
比 JS 重算更稳的替代方案:SVG
如果项目已用响应式布局、或需要支持无障碍(aria-label、focusable)、或热区形状复杂,直接改用 SVG 是目前最省心的解法。
关键点:
-
<svg viewBox="0 0 [origW] [origH]" width="100%">中的viewBox必须填原始图片尺寸,否则比例错乱 -
<image href="..." width="100%" height="100%">铺底图,所有热区元素(<rect>、<circle>、<path>)都基于该坐标系定位 - 坐标可直接写百分比:
x="10%" y="20%" width="15%" height="12%",缩放时自动重映射,无需 JS - 转换脚本很简单:
x_pct = (x_px / naturalW) * 100,批量处理 PS/Figma 导出的坐标即可
真正容易被忽略的是:SVG 方案里,viewBox 的宽高必须和原始图片像素尺寸一致。填错一个数字,整个热区比例就全偏了,而且很难一眼看出来。



















