应使用而非嵌入地图,因其支持矢量缩放、原生文本标签、事件绑定及无障碍访问;需配合与aria-label、focusable、响应式字体及多状态交互设计。

用 <svg></svg> 而不是 <img> 加文字图层
直接用 <img src="map.png"> 嵌入位图,后续加文本描述只能靠绝对定位覆盖,结果是文字不随缩放、不响应点击、无法选中、打印时错位。真正可行的路径是把地图本身写成 <svg></svg>:矢量可缩放,原生支持 <text></text>、<title></title>、<desc></desc> 和事件绑定。
实操建议:
- 从 GIS 工具(如 QGIS)导出 GeoJSON,再用
geo2svg或d3-geo转为路径数据,避免手绘复杂边界 - 用
<g id="province-beijing"></g>包裹每个区域,便于 JS 操作和 CSS 选择 - 文本描述统一用
<text x="..." y="..." font-size="12">北京市</text>,不要用<div> 叠加 <li>若需中文换行,SVG 不支持 <code>white-space: pre-wrap,得拆成多个<tspan></tspan>,例如:<text x="100" y="200"><tspan>面积:16410 km²</tspan><tspan x="100" dy="1.2em">常住人口:2189万</tspan></text>
- 用
aria-label="北京"但<title></title>写成 "Beijing" —— 多语言场景下信息割裂 - 把长描述全塞进
aria-label,导致读屏软件一次性播报过长,用户难捕捉重点 - 在
<path></path>上加<title></title>,但没给<path></path>设focusable="true",键盘 Tab 无法聚焦
aria-label 和 <title></title> 必须同时存在
只加 <title></title>(鼠标悬停提示)对屏幕阅读器不够友好;只加 aria-label 又丢失视觉提示。两者要配对使用,且内容需一致或互补。
常见错误现象:
正确写法示例:
<path d="M100,200 L150,200 ..." id="bj-path" tabindex="0" focusable="true"><title>北京市:华北平原北部,首都所在地</title></path>再配合 JS 绑定
keydown 监听 Enter 触发详情弹窗。
响应式缩放时文本大小不能固定 font-size
SVG 内部单位默认是像素,设 font-size="12" 在 2x 屏幕上会模糊,缩放到 200% 时文字也不放大——看起来像被“压扁”了。
解决方案分两种场景:
- 纯 SVG 文件独立使用:用
viewBox+preserveAspectRatio,文字用font-size="1em",靠父容器 CSS 控制整体缩放 - 内联 SVG(
<svg></svg>直接写在 HTML 中):JS 监听window.resize,动态计算缩放比,重设所有<text></text>的font-size属性值 - 更稳妥的做法是放弃固定字号,改用
transform="scale(0.8)"配合font-size="15",让文字和图形同步缩放
交互高亮别只靠 :hover,要考虑触摸和焦点
仅写 path:hover { fill: #ff6b35; } 在手机端完全无效,且对键盘用户不友好。
必须补充:
- CSS 中加上
path:focus { outline: 2px solid #4a90e2; },并确保所有可交互<path></path>有tabindex="0" - 用 JS 绑定
click和keydown(监听Space和Enter),手动切换data-active="true"状态 - 避免用
fill动画做高亮,低端设备易掉帧;改用stroke+stroke-width变化更轻量
复杂点在于:地图区域边界常由多段 <path></path> 拼成,高亮时需批量操作,建议用 document.querySelectorAll('[data-region="beijing"]') 而非硬编码 ID 列表。











