关于 maps
面向地图实现与审查的无障碍技能,适用于静态地图和交互地图。它强调依据地图任务提供同步的结构化替代内容,并覆盖键盘操作、触控替代方案及第三方嵌入检查。
主要功能
- 01按地图用途选择替代内容
- 02提供地点列表或路线说明
- 03检查键盘操作与焦点管理
- 04为拖动和触控提供替代操作
- 05避免仅依赖颜色传达信息
适用场景
- 01审查服务地点地图
- 02为地图补充可访问的路线说明
- 03检查交互地图和第三方嵌入
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mgifford/ accessibility-skills --skill maps安装后在 Claude Code 中输入/maps确认已加载。
附带文件SYNC.md
详细介绍
地图无障碍技能
规范来源:
mgifford/ACCESSIBILITY.md中的examples/MAPS_ACCESSIBILITY_BEST_PRACTICES.md此技能源自该文件。如有疑问,以该示例为准。
实现或审查任何静态或交互式地图时,请遵循这些规则。 仅当项目包含地图时,才加载此技能。
核心要求
没有一种文本描述适用于所有地图。首先明确地图的用途及其支持的任务,然后为无法看见、辨别、指向、拖动、缩放或解读地图视觉信息的人提供无障碍内容和控件,同时保留地图的用途。地图及其结构化替代内容应使用同一数据源并保持同步。
严重程度(本技能)
| 级别 | 含义 |
|---|---|
| 严重 | 关键位置数据没有无障碍替代内容 |
| 较严重 | 交互式地图无法通过键盘访问;误用 role="application" |
| 中等 | 缺少跳过链接;颜色区分能力不足;未管理弹出窗口焦点 |
| 轻微 | 动画缺少 prefers-reduced-motion;图例不完整 |
首先判断地图的用途
| 地图用途 | 关键任务 | 常见的无障碍呈现方式 |
|---|---|---|
| 简易定位图 | 确定某处位置及前往方式 | 简洁的替代文本、地址、地标、路线说明、联系信息 |
| 地点目录 | 查找并比较服务 | 可搜索的列表或表格,包含名称、地址、距离、类别 |
| 路线/导航 | 从 A 点前往 B 点 | 按顺序提供路线说明,包含距离、转弯、地标、路况 |
| 专题/定量地图 | 比较不同区域的数值 | 摘要及数据表,包含区域名称、数值、单位、时间段 |
| 边界/分区图 | 了解包含关系/相邻关系 | 标明边界的说明、受影响地点、可下载数据 |
| 室内/多楼层地图 | 在建筑内导航 | 楼层选择器、无障碍路线说明、出入口/电梯/楼梯 |
| 探索型地图 | 探索空间关系 | 同步筛选器、结构化结果、无障碍查询工具 |
一张地图可能有多种用途——请针对每项关键任务提供所需的替代内容,不要认为简短的 alt、表格或路线说明放之四海而皆准。WCAG 1.1.1 中的“等效目的”并不意味着重现每个像素或街道名称,而是保留特定情境下重要的信息和任务。研究(地图等效目的框架)发现,如果地图用途包含广泛的空间理解或探索,表格和逐步路线说明可能并不足够——请将其视为指导,而非独立的 WCAG 标准,同时注意仅靠表格何时无法满足需求。
严重:静态地图的文本替代内容
<figure>
<img src="clinic-location.png"
alt="The clinic is on the north side of King Street, immediately east of the Central Station entrance."
width="960" height="540">
<figcaption>
Northside Clinic, 200 King Street. The step-free entrance is on King Street.
<a href="#clinic-directions">Read accessible travel directions</a>.
</figcaption>
</figure>
不要在 alt 中塞入逐步路线说明或所有道路名称——保持简洁,并将详细信息放在附近。对于复杂地图,请同时提供简短的替代内容,以及可见的结构化长描述或关联明确的链接:
<figure>
<img src="accessible-transit-routes.png"
alt="Map of step-free transit routes in the downtown area. Detailed route information follows."
width="1200" height="800">
<figcaption>
Step-free transit routes, updated 15 July 2026.
<a href="#transit-route-details">View route details and connections</a>.
</figcaption>
</figure>
对于复杂描述,优先使用可见的结构化内容,而非 aria-describedby——辅助技术通常会将引用的标题/列表/表格压平为一段字符串,导致其结构无法导航。只有在图片纯属装饰,或相同信息已在附近完整提供时,才适合使用 alt=""——切勿将有意义或可交互的地图称为装饰内容,以掩盖无障碍问题。
严重:与任务匹配的结构化替代方案
位置列表/表格(适用于目录):
<table id="branch-table">
<caption>Library branches matching the current filters</caption>
<thead>
<tr><th scope="col">Branch</th><th scope="col">Address</th><th scope="col">Distance</th><th scope="col">Accessibility information</th></tr>
</thead>
<tbody>
<tr>
<th scope="row"><a href="/branches/central">Central Library</a></th>
<td>100 Main Street</td><td>600 metres</td>
<td>Step-free entrance, lift, accessible washroom, hearing loop</td>
</tr>
</tbody>
</table>
说明距离的计算方式;注明单位;保留筛选和排序顺序;让用户能够从地图和列表视图打开相同的详情并执行相同的操作。
路线指引:
<section id="clinic-directions" aria-labelledby="directions-heading">
<h2 id="directions-heading">Step-free route from Central Station</h2>
<p>Distance: 350 metres. Typical travel time: 6 to 10 minutes.</p>
<ol>
<li>Leave Central Station through the King Street step-free exit.</li>
<li>Turn left and continue east for approximately 250 metres.</li>
</ol>
<p>Route data checked 15 July 2026. Call 555-0100 to confirm temporary closures.</p>
</section>
视情况包括:距离/行程时间;街道名称/地标/转弯处;路缘坡道/过街设施/坡度/路面/台阶;无障碍入口/电梯/洗手间;已知的施工/封闭路段;公共交通站点/站台信息;以及最短路线无法无障碍通行时的替代路线。不要只依赖方位描述——应结合街道名称、距离和地标。
**专题地图/定量地图:**提供通俗易懂的摘要、包含比较所需全部数值的数据表、区域名称/类别/单位/缺失数据标识,以及时间段/来源。不要用颜色名称列表替代分级设色地图。
图例是内容,而非装饰——将图例文本放在 HTML 中,描述颜色/符号/图案/线型/大小,并确保其随活动图层同步变化;绝不要让图例成为唯一的结构化替代方案。
严重:交互式地图页面结构和跳过链接
<section aria-labelledby="service-map-heading">
<h2 id="service-map-heading">Find an accessible service location</h2>
<p><a href="#location-results-heading">Skip the interactive map and view locations</a></p>
<div class="map-interface">
<h3 id="map-view-heading">Interactive map</h3>
<p id="map-instructions">Use the named map controls to move or zoom.</p>
<div id="map-viewport" role="region" aria-labelledby="map-view-heading"
aria-describedby="map-instructions">
</div>
</div>
<section aria-labelledby="location-results-heading">
<h3 id="location-results-heading" tabindex="-1">Location results</h3>
<p id="location-result-status" role="status" aria-atomic="true"></p>
<ul id="location-results"></ul>
</section>
</section>
**交互式地图缺少跳过链接属于严重问题。**指向结果的可见链接对屏幕阅读器、键盘、开关设备、语音输入、移动设备、低带宽环境和认知障碍用户都很有用——不要只在键盘聚焦时显示。
严重:第三方地图嵌入
<iframe src="https://maps.example.org/embed/service-locations"
title="Interactive map of service locations" loading="lazy"></iframe>
<p><a href="#service-location-list">View service locations as a list</a>
or <a href="/service-locations.csv">download the location data</a>.</p>
没有描述性 title 的 <iframe> 属于严重问题。确认键盘用户能够进入/操作/离开嵌入内容;测试控件、标记、弹出窗口、同意提示和全屏模式;将结构化替代方案放在 iframe 之外,以便在提供方失效或被屏蔽时仍可使用;确认嵌入内容中的更改会反映在网站的替代方案中;在提供方/插件/配置更新后重新测试。不要未经测试当前实际呈现的体验,就轻信提供方关于无障碍性的声明。
**地图库:**除非测试结果支持更改,否则保留地图库的无障碍默认设置(例如,Leaflet 的容器/标记默认支持键盘操作——插件可能会降低无障碍性)。固定版本,查看发行说明,并在更新后重新测试——不要声称某个插件普遍适用于无障碍场景,也不要在生产环境中使用未固定版本的 @latest。
严重:键盘控制与 role="application"
除非底层移动操作属于必要功能(WCAG 的有限例外),所有地图功能都必须可通过键盘访问。
<div class="map-controls" role="group" aria-labelledby="map-controls-heading">
<h3 id="map-controls-heading">Map view controls</h3>
<button type="button">Zoom in</button>
<button type="button">Pan north</button>
<button type="button">Reset map view</button>
</div>
用户可以按逻辑顺序访问每个控件;原生按钮可通过 Enter/
Space 操作;焦点始终可见,且不会被浮动控件或弹出窗口遮挡;用户可以进入和离开地图,不会陷入焦点陷阱;地图重新渲染时不会丢失焦点或将焦点移至 <body>。不要仅仅因为页面上有地图就捕获页面级方向键——只有在视口获得焦点时才启用方向键平移,并始终允许用户通过 Tab/Shift+Tab 离开。单字符快捷键必须符合 WCAG 2.1.4(关闭/重新映射/限定作用范围),并提供带名称的按钮作为替代方式。
大多数地图不需要 role="application"。 它会改变屏幕阅读器的交互模式,并禁用常规阅读命令。优先使用地图周围的原生控件、用于显示结果的常规文档内容、带名称的视口区域,以及仅在视口需要时提供有文档说明且限定作用范围的键盘操作。误用属于严重问题——只有当团队了解其对 AT 的影响、已实现完整的键盘模型、提供了操作说明和退出方式,并测试了受支持的组合时,才使用 application 语义。添加该角色并不能让地图变得无障碍。
大量标记: 数百个标记不得产生数百个连续的 Tab 停靠点。选择经过测试的模式:地图视口作为一个 Tab 停靠点,并提供有文档说明的方向键导航;在当前标记集中使用 roving tabindex;仅在缩小结果范围后让标记可获得焦点;或将结构化位置列表作为主要键盘界面。没有通用的 WAI-ARIA 地图模式——请记录所选行为并进行测试。
中等:标记、聚合标记与弹出窗口的焦点管理
<button type="button" class="map-marker" aria-label="City Hall, 123 Main Street"
aria-expanded="false" aria-controls="city-hall-details">
<svg aria-hidden="true" focusable="false"></svg>
</button>
<section id="city-hall-details" aria-labelledby="city-hall-heading" hidden>
<h3 id="city-hall-heading">City Hall</h3>
<p>123 Main Street. Step-free entrance on Queen Avenue.</p>
<a href="/locations/city-hall">City Hall details</a>
</section>
同时更新 hidden 和 aria-expanded。标记弹出窗口应使用普通非模态内容——不要为每个标记弹出窗口添加 role="dialog"/aria-modal="true",只有当交互确实是模态时才添加。如果弹出窗口包含大量内容且焦点会移入其中,请提供关闭控件,并在关闭时将焦点返回触发该弹出窗口的标记。不要在原生按钮的名称中加入“按 Enter”之类的说明——其角色已传达了操作方式。
聚合标记需要可访问名称、数量和键盘操作:
<button type="button" aria-expanded="false" aria-controls="downtown-location-results">
Show 7 locations in downtown
</button>
展开时同时更新 aria-expanded 和两个视图;将焦点保留在聚合标记控件上,或仅在用户执行明确操作后将其移至可预测的结果标题;播报简明的结果摘要,而不是每个标记。
中等:不单独依赖颜色
切勿单独依赖颜色来区分路线/区域/状态——除颜色外,还要使用路线编号和线型;除标记颜色外,还要使用图标和文本标签;除区域填充外,还要使用图案或边界样式;数据表中还要包含数值。仅依赖颜色编码属于中等问题(如果颜色区分的是具有不同安全影响的路线/状态,则属于严重问题)。请在强制颜色模式下测试——地图图块背景可能会被覆盖;如果图块或渐变消失,请确保位置列表/路线说明仍然完整。
对比度:作者设置的普通文本 ≥4.5:1;大号文本 ≥3:1;用于识别控件/状态/图形对象的必要视觉信息 ≥3:1(WCAG 1.4.11);焦点指示器相对于其所在背景必须具有足够的对比度。不要声称每个像素、航拍照片或附带标签都必须符合统一的对比度;应评估实际理解和操作地图所需的作者提供的信息。
中等:目标尺寸
WCAG 2.5.8 要求至少为 24×24 CSS 像素,或符合列出的例外情况——它并未在 AA 级别普遍要求 44×44。将主要地图控件设为 44×44,是一种包容性实践,与 AAA 级别的增强目标尺寸标准(2.5.5)一致,而不是因为 AA 有此要求:
.map-controls button { min-inline-size: 44px; min-block-size: 44px; }
只要点击区域之间不会出现含糊的重叠,标记在视觉上可以较小,同时拥有更大的透明点击区域。
严重:指针、触控和拖动的替代方式
地图通常依赖捏合、旋转、滑动和拖动——这些不能成为操作关键功能的唯一方式。提供缩放按钮作为捏合操作的替代方式;提供平移控件、搜索和选择作为拖动操作的替代方式;提供按钮或菜单,作为拖动标记或路线点的替代方式;支持通过单指针激活标记和控件;让操作在指针抬起时完成,而不是在按下时完成。
嵌入式地图不得造成页面滚动陷阱——用户需要一种可靠的方式滚动经过地图,而不必使用未说明的多指手势。尤其是在小屏幕上,可考虑要求用户先明确执行“使用交互式地图”操作,再让地图捕获拖动或滚轮手势。
图层切换、搜索和地理定位
<fieldset>
<legend>Locations to show</legend>
<label><input type="checkbox" name="category" value="clinic" checked> Clinics</label>
<label><input type="checkbox" name="step-free" value="yes"> Step-free entrance</label>
</fieldset>
播报简洁的结果摘要(“显示 12 个地点”)——不要播报每个新增的标记、加载的地图切片、平移动作或缩放画面。
**搜索:**带标签的搜索表单、状态消息和普通链接,比自定义自动补全控件更容易实现和使用。如果需要提供建议,请实现并测试完整的 WAI-ARIA 组合框模式——仅在其他方面不完整的控件上添加 role="listbox"/aria-autocomplete 并不足够。接受多种输入形式;说明错误,但不要清除查询;播报简洁的结果数量;标明有歧义的地址,并让用户选择;在地图视图和列表视图之间切换时保留查询和筛选条件。
**地理定位:**仅在用户明确操作后请求权限;说明请求原因和用途;用户拒绝授权时提供地址或地点搜索;妥善处理过时或不准确的位置,不要归咎于用户;对于可以手动输入完成的任务,不要要求精确地理定位。
弱视力、缩放、重排和方向
浏览器缩放和地图缩放并不相同——两者都要支持,绝不要在页面级别覆盖浏览器缩放或捏合缩放。确保在浏览器缩放至 200%/400% 时,地图控件和替代方式仍可用;支持纵向和横向;避免固定高度布局在文本增大时隐藏控件。WCAG 1.4.10 关于二维布局的例外情况可以适用于地图视口本身,但不能免除周边控件、搜索、状态、详情、路线和位置结果遵守重排要求。
Canvas 和 SVG 地图
Canvas 像素没有子元素语义——如果地图绘制在 <canvas> 上,请在外部提供可访问的 DOM 控件、结果、名称、状态和替代方式,或在经过测试的回退结构中提供;不要假设屏幕阅读器能够检查绘制的标记。对于 SVG 地图:为非交互式地图提供恰当的可访问名称和说明;将装饰性路径排除在无障碍树之外;确保交互区域可通过程序聚焦并具有名称;为大型或复杂的 SVG 地图提供结构化的替代方式。请参阅 skills/svg/SKILL.md。
室内地图和寻路
根据实际情况提供:建筑物、入口、楼层和目的地名称;无障碍入口及开放时间;电梯、楼梯、自动扶梯、坡道和站台位置;走廊宽度、门的类型、门槛、坡度、地面材质和照明;洗手间、避难区域和协助点;地标以及决策点之间的距离;电梯临时停运、施工和封闭信息;数据来源和最后核验日期。
<label for="floor-select">Building floor</label>
<select id="floor-select">
<option value="ground">Ground floor: entrance, reception, cafe</option>
<option value="1">Floor 1: offices and meeting rooms 101 to 120</option>
</select>
<p id="floor-status" role="status" aria-atomic="true"></p>
发生变化时,请同步更新楼层标题、地点、路线指引和地图。实时定位是增强功能,不应成为唯一的导航方式——室内定位可能不准确或无法使用;请提供静态路线指引,以及报告路线数据过时的方式。
数据质量与无障碍信息
无障碍呈现无法纠正不准确的地理数据。注明数据来源和最后更新日期;说明距离是直线距离、步行距离、驾车距离还是公共交通距离;区分经过核实的无障碍信息与用户提交或推断的信息;提供报告错误和临时障碍的方式;保留缺失/未知值,不要将其显示为“否”;条件可能变化时,避免对路线作出绝对断言;如果出行前需要确认某项关键无障碍设施,请提供联系信息。
测试
- **目的等效性:**列出地图记录的用途/必要任务;先使用可视化地图完成每项任务,再仅使用结构化替代方案和非地图控件完成;比较可获取的信息、结果和结论;酌情邀请盲人、低视力人士、行动障碍人士、认知障碍人士和聋盲人士参与测试。不要只检查是否存在表格,就判定目的等效。
- **键盘:**通过键盘访问并操作搜索、筛选器、图层、控件、标记、聚合标记、详情、结果和全屏功能;确认焦点顺序合理且可见;确认地图更新不会导致焦点丢失;确认进入和离开视口及嵌入地图时不会发生键盘陷阱;确认结构化替代方案支持相同操作
- **屏幕阅读器:**确认控件、标记、聚合标记、状态和结果均具有实用的名称和角色;检查状态消息是否简洁且不会重复过多;可独立于地图阅读结构化描述、表格和路线说明;确认打开/关闭详情不会导致意外的焦点变化
- **视觉/低视力:**测试浏览器缩放至 200%/400% 的情况;测试窄视口和横竖屏方向;测试文本间距、浅色/深色/强制颜色模式;确认标签不会消失或重叠;确认无需依靠颜色也能区分选中状态、路线和边界;确认隐藏地图图像后,替代方案仍可使用
- **指针/触控:**仅使用单一指针完成每项任务;无需双指缩放或拖动即可缩放/平移;检查是否提供拖动标记/路线点之外的替代操作;检查目标尺寸、间距和指针取消行为;确认页面滚动经过地图时不会发生陷阱
- **数据/集成:**将标记数量/内容与结构化结果进行比较;应用每项筛选条件,确认两种视图保持同步;核实距离/单位/坐标/无障碍属性;测试无结果/加载中/错误/离线/权限被拒绝等状态;数据/底图/库更新后重新测试
自动化检查可以检测缺少 iframe 标题、无名称按钮、无效 ARIA、重复 ID、焦点顺序回归、对比度问题、缺少静态图像替代方案以及地图/列表数量不匹配——但无法判断目的是否等效、方向是否准确、路线是否无障碍、空间理解是否到位,或第三方键盘操作行为。必须进行人工测试和用户测试。
常见问题
| 问题 | 修正方法 |
|---|---|
使用通用的 alt="Map" | 描述地图的用途,并提供适合任务的结构化替代内容 |
| 认为表格或路线说明总能完全等效 | 根据文档中说明的用途匹配替代内容;必要时补充空间描述 |
仅通过 aria-describedby 提供复杂表格 | 提供可见、可导航的 HTML,或提供关联清晰的链接 |
默认给地图添加 role="application" | 使用命名区域、原生控件、普通内容和范围限定的键盘行为 |
| 在焦点位于页面其他位置时捕获方向键 | 仅在视口获得焦点时响应地图方向键;提供命名控件 |
| 让每个标记都成为 Tab 停靠点 | 使用经过测试的导航模型,并与位置列表同步 |
将每个弹出窗口都设为 aria-modal="true" 对话框 | 除非确实需要模态,否则使用普通的非模态详情 |
| 声称 WCAG AA 普遍要求 44×44 的目标尺寸 | 应用 24×24 的 AA 级标准;将 44×44 作为包容性/AAA 实践 |
| 混淆 2.4.11(焦点不被遮挡)与 2.4.13(焦点外观) | 2.4.11 是焦点不被遮挡(最低要求,AA);焦点外观是 2.4.13(AAA) |
| 只提供捏合或拖动作为交互方式 | 提供单指针按钮和选择替代方式 |
| 对地图上的每个像素都应用同一对比度 | 准确测试重要的作者撰写文本、控件、状态和图形对象 |
| 将交互式地图隐藏为装饰内容以规避修复 | 移除交互功能,或提供可访问的控件/信息/替代内容 |
| 播报每次平移、瓦片或标记更新 | 播报简洁的任务完成结果;保持持久内容可见 |
| 未经测试就信任地图提供商或插件 | 测试当前配置的版本;保留外部结构化替代内容 |
| 地图和位置列表使用不同的数据 | 从同一数据源和状态生成两者 |
完成标准检查清单
- 已记录地图的用途、受众和关键任务
- 静态地图具有简洁的替代文本;复杂地图具有可见的结构化描述
- 位置列表/表格/路线说明清晰可见、结构明确且易于查找
- 地图和非地图视图使用相同的数据、筛选条件和结果状态
- 每个交互式地图之前都有跳过链接
- 第三方
<iframe>地图具有描述性title;替代内容位于 iframe 外 - 所有地图交互均可通过键盘操作;方向键平移仅在视口获得焦点时生效
- 仅在自定义键盘模型经过完整测试时才使用
role="application"——不得默认使用 - 大量标记使用经过测试的导航模型,而不是设置数百个 Tab 停靠点
- 标记弹出窗口为非模态,除非确实需要模态;关闭时焦点返回触发控件
- 不单独依靠颜色进行区分;提供图例;在强制颜色模式下进行测试
- 目标尺寸至少为 24×24px;实际可行时,主要控件使用 44×44px
- 捏合/拖动/路径手势均提供单指针按钮替代方式
- 地图控件/替代内容在 200%/400% 缩放和窄视口下仍可使用
- 状态消息简洁;持久结果在页面中保持可见
- 已记录数据源、日期、单位和限制
WCAG 核心标准
- 1.1.1 非文本内容(A)——如果没有文本替代内容,则为严重问题
- 1.3.3 感官特征(A)
- 1.4.1 颜色的使用(A)——如果仅用颜色编码,则为中等问题
- 1.4.3 对比度(最低)(AA)
- 1.4.10 重排(AA)——地图视口本身有明确的例外情况
- 1.4.11 非文本对比度(AA)
- 2.1.1 键盘(A)——如果地图控件无法通过键盘操作,则为严重问题
- 2.1.4 字符键快捷方式(A)
- 2.4.3 焦点顺序(A)
- 2.4.11 焦点不被遮挡(最低)(AA,WCAG 2.2)——不是焦点外观
- 2.5.5 目标尺寸(增强)(AAA)——44×44 阈值
- 2.5.7 拖动动作(AA)
- 2.5.8 目标尺寸(最低)(AA)——24×24,这是实际的 AA 要求
- 4.1.2 名称、角色、值(A)
- 4.1.3 状态消息(AA)
参考资料
- 完整的最佳实践指南
- Leaflet:Leaflet 无障碍基础指南
- Mapbox GL JS 无障碍功能
- W3C WAI:复杂图像
- W3C WAI-ARIA APG:组合框模式
- 系统化评估数字地图的等效用途
**标准展望:**这些规则以 WCAG 2.2 AA 为目标。 请关注:https://www.w3.org/TR/wcag-3.0/