area 元素无法直接承载状态标识,必须通过外部手段(如 SVG 替代、覆盖层或 JS 同步)实现可访问的状态反馈,核心在于焦点管理、语义同步与视觉反馈闭环。

area 元素本身不支持 aria-current 或 class 动态切换
HTML 的 是 void 元素,不能包裹内容,也不能直接响应 :hover 以外的伪类(如 :focus-visible 在部分浏览器中受限),更无法原生承载状态标识(比如“当前选中”“已访问”“禁用”)。你看到的状态效果,实际必须靠外部手段驱动。
常见错误是试图给 直接加 class="active" 或 aria-current="page" 并期望它自动高亮或被读屏识别——这不会生效,因为 没有渲染盒,也不参与 ARIA 流程中的可聚焦/可声明状态链。
- 状态标识必须映射到对应的视觉反馈载体(通常是其关联的
上的叠加层、SVG,或独立的 DOM 节点) -
唯一能做的,是通过href、alt、aria-label提供语义,以及用tabindex="0"获得键盘焦点(需配合 JS 手动管理焦点逻辑) - 如果用
+,务必确保usemap属性值与的name严格匹配(大小写敏感),否则整个映射失效
用 SVG 替代 map/area 实现可控状态
这是目前最可靠、可访问性最好的方案:把图像区域转为 SVG 或 ,每个图形元素都可直接绑定 class、aria-current、tabindex 和事件监听器。
示例片段:
<svg viewbox="0 0 800 600" focusable="false"><image href="floorplan.png" width="800" height="600"></image><path id="room-101" d="M120,80 L220,80 L220,160 L120,160 Z" class="room" tabindex="0" aria-label="会议室 101" aria-current="false"></path><path id="room-102" d="M240,80 L340,80 L340,160 L240,160 Z" class="room" tabindex="0" aria-label="休息区 102" aria-current="false"></path></svg>
- 点击或键盘操作后,用 JS 切换
aria-current="true"和 CSS class(如.room[aria-current="true"] { stroke: #007bff; stroke-width: 3; }) - 必须为
设置focusable="false",避免整块 SVG 被当作一个焦点项;让焦点落在具体上 - IE 不支持
的tabindex,若需兼容,得用包裹并设tabindex,再透传事件
保留
如果必须用传统图像映射(例如遗留系统、CMS 输出不可改),只能靠 JS + 绝对定位的覆盖层来“伪造”状态标识。
- 用 JS 读取每个
的coords和shape,计算出对应区域的 DOM 覆盖节点(或)位置和尺寸- 覆盖层需设置
pointer-events: none,仅用于展示;交互仍由触发,JS 同步更新覆盖层的class和aria-hidden- 注意响应式:当图片缩放时,
coords值不会自动适配,必须监听window.resize并按比例重算覆盖层位置- 读屏软件看不到覆盖层的状态,所以必须同步更新
的aria-label(例如追加 “(当前选中)”)别忽略键盘与屏幕阅读器的协同逻辑
无论用 SVG 还是覆盖层,只要用户能通过 Tab 进入某个区域,就必须保证:焦点可见、状态可宣布、操作可撤销。
- 给可聚焦区域加
outline: 2px solid #007bff(不要用outline: none) - 用
aria-live="polite"容器播报状态变更(例如 “已选中会议室 101”),而不是只靠视觉变化 - 按 Enter/Space 触发操作后,若状态改变,应立即更新
aria-current和视觉样式;若只是预览,需提供明确的确认/取消机制 - 移动端 Safari 对
的触摸支持不稳定,建议在 touchstart 时主动preventDefault()并触发 click 模拟
真正的状态标识不在标签里,而在行为链中:焦点 → 键盘操作 → JS 状态更新 → 视觉反馈 → 语义播报。漏掉任一环,对部分用户就是不可用。
- 覆盖层需设置
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











