area标签在响应式布局中无法直接使用,因其coords基于图片原始尺寸而非渲染尺寸,缩放后热区错位;必须用js动态重算坐标或改用svg方案。

area 标签在响应式布局里根本不能“直接用”——它不随图片缩放重映射坐标,写死的像素值在移动端必然点不准。必须换方案或加 JS 补偿。
为什么 area 的 coords 在缩放后失效
浏览器把 coords 绑定到图片的 naturalWidth/naturalHeight,不是当前渲染尺寸。CSS 设置 width: 100% 或 max-width 只改变显示大小,area 热区仍按原始像素定位,导致点击漂移。
- 常见现象:
area在桌面正常,手机上点击完全无反应,控制台却没报错 -
coords="0,0,100,100"永远指原始图左上角 100×100 像素区域,哪怕图被缩成 50px 宽 -
transform: scale()、object-fit都无效——它们只影响渲染,不触发热区重算
必须用 JS 动态重算 coords 的实操要点
若受限于 CMS 或遗留系统无法替换为 SVG,就得监听 img.load 和 window.resize,手动更新每个 area.coords。
- 先取原始尺寸:
const w0 = img.naturalWidth; const h0 = img.naturalHeight; - 再算缩放比:
const scaleX = img.offsetWidth / w0; const scaleY = img.offsetHeight / h0;(注意用offsetWidth/Height,不是clientWidth/Height) - 对每种
shape分别处理:rect拆四数、circle拆三数、poly每两数一组,分别乘对应比例 - 更新前要确保
img已加载完成,否则naturalWidth是 0;<picture></picture>场景需绑定到最终加载的<img>实例,而非父容器
更推荐的现代替代:用 svg 替代 map+area
svg 天然支持响应式热区,靠 viewBox 和百分比坐标即可,无需 JS 干预,且语义清晰、可访问性好。
-
<svg viewbox="0 0 [origW] [origH]" width="100%"></svg>中的viewBox必须填原始图片宽高,否则比例错乱 -
<image href="plan.png" width="100%" height="100%"></image>铺底图,所有热区元素(<rect></rect>、<path></path>)都基于同一坐标系 - 坐标可直接写
x="10%"、points="10%,20% 15%,18% ...",缩放时自动重映射 - 支持
aria-label、focusable="true"、tabindex,无障碍比area更可靠
usemap 与 <map name></map> 匹配失败是静默失效的头号原因
90% 的“area 不工作”问题其实跟响应式无关,而是关联断裂——浏览器不报错,只让整个热区彻底消失。
-
usemap="#floor-plan"和<map name="floor-plan"></map>必须逐字节一致:大小写、连字符、不能用下划线代替 -
<map></map>必须是内的普通 DOM 节点,不能在<template></template>、<shadow-root></shadow-root>或<picture></picture>内部 -
area必须是map的**直接子元素**,中间插个<div> 就失效 <li>调试方法:右键图片 → “检查”,看能否高亮到对应 <code><map></map>;不能则基本是匹配失败
真正麻烦的不是怎么写 coords,而是每次图片尺寸变化都要同步更新热区逻辑——SVG 方案省掉这层耦合,viewBox 一设,其余全是声明式。如果非要用 area,就别幻想 CSS 能搞定适配,JS 重算和严格匹配才是绕不开的硬门槛。











