原生 + 在响应式页面中必然失效,因其 coords 基于图片原始像素而非渲染尺寸,缩放后热区错位;必须动态重算坐标或改用 SVG 方案。

原生 <map></map> + <img alt="如何在HTML中制作响应式可点击区域" > 在响应式页面中必然失效,除非你放弃 CSS 缩放、用固定尺寸图片配多套 <map></map>,否则必须引入动态重算或换技术栈。
为什么 <map></map> 的 coords 在响应式下点不准
coords 值永远基于图片原始像素(img.naturalWidth/img.naturalHeight),不是浏览器渲染后的尺寸。你写 img { width: 50%; height: auto; },图片缩成一半,但 coords="100,100,200,200" 还是按原图 1600×900 解析——热区实际落在左上角 1/16 区域外,根本点不中。
常见错误现象:
-
<img usemap="#product-map" alt="如何在HTML中制作响应式可点击区域" >漏了#,整个热区静默失效 -
<map name="ProductMap"></map>和usemap="#product-map"大小写/连字符不一致 -
<map></map>被包在display: none或visibility: hidden容器里,无法绑定
用 SVG 替代 <map></map> 是最省心的方案
SVG 天然支持缩放、坐标系自动适配视口,且语义完整、可访问性好。把图片当背景嵌入,用 <circle></circle>、<rect></rect> 或 <polygon></polygon> 定义热区,所有坐标直接按当前 SVG 尺寸写,无需换算。
立即学习“前端免费学习笔记(深入)”;
实操要点:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 用
<image href="photo.jpg" width="100%" height="100%"></image>铺满 SVG 画布 - 热区元素加
cursor: pointer和tabindex="0",支持键盘聚焦 - 每个热区必须带
href(或用<a></a>包裹)和aria-label,否则屏幕阅读器不可读 - 避免在 SVG 外层加
width/height再用 CSS 缩放——这会破坏内部坐标比例
如果必须用 <map></map>,重算 coords 是唯一可行路径
监听 img.load 和 window.resize,实时按缩放比修正所有 <area> 的 coords 值。别信“只改一次”——图片加载完成时尺寸可能未稳定,resize 后也要再跑一遍。
关键计算逻辑:
- 获取原始宽高:
const w = img.naturalWidth; const h = img.naturalHeight; - 获取当前渲染尺寸:
const rw = img.offsetWidth; const rh = img.offsetHeight; - 缩放比:
const sx = rw / w; const sy = rh / h; - 矩形热区:
coords四个值全部乘对应缩放比(x 坐标 ×sx,y 坐标 ×sy) - 圆形热区:圆心 x/y × 对应缩放比,半径 ×
Math.max(sx, sy)(避免椭圆)
建议直接用 rwdImageMaps 这类轻量库,手写容易漏掉 img.decode() 等异步时机问题。
移动端热区尺寸必须达标,否则真机点不中
44×44px 是触控最低物理尺寸要求,不是 CSS 像素。很多页面在桌面端看着正常,手机上反复点击无反应,就是这个原因。
检查项:
- 矩形热区:
coords="x1,y1,x2,y2"中x2 - x1 ≥ 44且y2 - y1 ≥ 44 - 圆形热区:
coords="cx,cy,r"中r ≥ 22 - 用
min-width: 48px; min-height: 48px包裹热区容器(如果用 JS 模拟点击),比固定width/height更可靠 - 务必在真机上测试——模拟器的 touch 事件精度和延迟与真实设备差异极大
最常被忽略的一点:热区偏移和点不中,90% 不是代码写错,而是没意识到 coords 和渲染尺寸毫无关系,或者忘了在移动端强制触控尺寸。


















