关于 speech-recognition
为实现或审查支持语音输入与语音控制的界面提供无障碍指导,面向设计师和开发者。内容涵盖标签、原生语义、文本输入、替代交互、反馈及测试。
主要功能
- 01匹配可见标签与无障碍名称
- 02使用原生语义和键盘操作
- 03支持听写、粘贴与自动补全
- 04为拖动和手势提供替代方式
- 05以视觉和程序方式呈现反馈
- 06记录并测试目标环境
适用场景
- 01审查语音控制下的控件名称
- 02处理语音听写后的表单校验
- 03为拖放和滑块设计替代操作
- 04测试语音工具与界面兼容性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mgifford/ accessibility-skills --skill speech-recognition安装后在 Claude Code 中输入/speech-recognition确认已加载。
附带文件SYNC.md
详细介绍
语音识别无障碍技能
规范来源:
mgifford/ACCESSIBILITY.md中的examples/SPEECH_RECOGNITION_ACCESSIBILITY_BEST_PRACTICES.md此技能源自该文件。如有疑问,以示例为准。
在实现或审查任何必须支持语音输入或语音控制的界面时,请遵循以下规则。
请与 keyboard/SKILL.md 一起加载——语音工具通常依赖键盘和指针模拟,因此键盘要求是基础,而非替代方案。
核心要求
语音识别可以听写文本、浏览界面、激活控件、模拟键盘输入以及操作指针。语音识别不同于说话人识别——语音识别负责解析词语和命令;说话人识别则试图辨认说话者的身份。
核心原则:
- 使用可见且持久的标签——用户必须能够确定要说什么,而不必猜测隐藏的名称
- 让可见标签与无障碍名称一致——如果控件有可见文本,其无障碍名称必须包含该文本
- 使用原生语义——正确的 HTML 名称、角色、状态、值和键盘行为能为语音工具提供可靠信息
- 支持直接激活标签以外的方式——键盘模拟、名称/数字叠加层和指针模拟因产品而异
- 不要要求精细的指针控制——为拖动、路径手势和精确的空间交互提供替代方式
- 接受按键事件以外的输入——听写、粘贴和自动补全可能会更改字段,却不会触发预期的按键事件
- 提供明确反馈——以视觉和程序化方式呈现状态变化、错误、确认信息和结果
- 测试受支持的环境——命令、叠加层和行为因产品、平台和版本而异
**语音输入的使用者:**活动能力、力量、灵活性、伸展能力或耐力有限的人;患有重复性劳损、疼痛、震颤或疲劳的人;使用语音代替或配合键盘/指针的人;认为听写比打字更轻松的认知/学习障碍者;暂时或因情境而受限的人;将语音与屏幕阅读器、放大镜或开关设备配合使用的人。语音用户不一定能看见——不要假设所有语音用户都能看见标签、叠加层、指针、焦点指示器或视觉结果,并据此进行设计或测试。
严重程度级别(此技能)
| 级别 | 含义 |
|---|---|
| 严重 | 语音工具无法通过任何方式(名称、叠加层或键盘/指针模拟)激活控件 |
| 高 | 无障碍名称不包含可见标签;验证仅依赖 keydown,并会静默拒绝听写或粘贴的输入 |
| 中 | 难以区分重复控件;仅图标控件没有无障碍名称 |
| 低 | 隐藏上下文插入在可见标签之前而非之后;名称的本地化不一致 |
严重:可见标签必须包含在无障碍名称中(WCAG 2.5.3)
对于包含可见文本或文本图片的组件,无障碍名称必须包含该可见文本——将其放在名称的开头是文档中建议的最佳实践,而非额外的规范性要求。
<button type="submit">Save</button>
<button type="submit" aria-label="Confirm changes">Save</button>
<button type="submit" aria-label="Save document">Save</button>
aria-label/aria-labelledby 可以覆盖从子内容派生的名称——应检查计算后的无障碍名称,而不是假设所有标签来源都会合并。不要将占位符文本作为唯一标签——它可能在听写过程中消失,且不能替代以编程方式关联的 <label>。
确保可见词语连续且顺序不变:
<button>Delete <span class="visually-hidden">quarterly report</span></button>
<button aria-label="Delete the quarterly report permanently">Delete report</button>
第二个示例包含“Delete”和“report”,但在两者之间插入了其他词语——某些语音工具可能无法匹配用户看到的短语。如果可见文本仍完整呈现,隐藏的前缀(出现在可见词语之前的上下文)并不一定违反 2.5.3,但仍可能让用户更难直接激活标签——最好不要在用户看到的文本前放置隐藏词语。应将格式提示/约束放入 aria-describedby 描述中,而不是名称中。
严重:区分重复控件,但不要重命名它们
重复的标签(“Edit”“Delete”“Read more”)可能让语音工具提供多个匹配项——这不一定构成不符合规范,但会增加操作难度。简短时,优先使用具体的可见标签:
<a href="/services">Read about services</a>
<a href="/products">Read about products</a>
对于紧凑的重复操作,应在可见操作词语之后添加上下文文本:
<li>
Billing address
<a href="/account/billing/edit">Edit <span class="visually-hidden">billing address</span></a>
</li>
不要通过替换或调整可见标签的顺序来让无障碍名称变得唯一——对于可见标签为“Edit”的链接,“Modify billing address”并不是合适的隐藏名称。
中等:仅图标控件
仍需要符合 WCAG 4.1.2 的无障碍名称(没有可见文本标签时,2.5.3 不适用):
<button type="button" aria-label="Close dialog">
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
<path d="M6 6 18 18M18 6 6 18"></path>
</svg>
</button>
持久可见的文本通常比单独的图标更容易被发现。仅在悬停/聚焦时出现的工具提示不是持久可见标签——用户必须先发现或定位控件,工具提示才能发挥作用。如果保留仅图标设计:使用简洁的本地化名称;一致地使用熟悉的图标;提供足够的目标尺寸/间距;确保名称/编号叠加层能标识控件;不要仅通过颜色或位置进行说明;使用受支持的语音工具进行测试。
严重:原生语义与键盘操作
语音工具通常使用无障碍 API、键盘模拟或指针模拟——原生 HTML 可直接提供可靠的角色/名称/状态/值/焦点/激活行为。
<div class="button" onclick="saveDocument()">Save</div>
<button type="button" onclick="saveDocument()">Save</button>
不要发布声称某个特定口述短语对每种角色都始终有效的表格——命令语法因语音产品、平台、区域设置和版本而异。正确的语义仍能提升兼容性,且对其他辅助技术依然是必需的。所有功能都必须支持通过键盘界面使用(除非该功能需要与路径相关的输入)——语音软件可以将键盘界面作为一种操作方式。对于自定义控件:仅当没有合适的原生元素时才使用正确的角色;实现预期的键盘交互;公开名称/状态/属性/值;在视觉状态变化时更新编程状态;遵循成熟的 APG 模式。请参阅 skills/keyboard/SKILL.md。
严重:听写和文本输入不能只依赖 keydown
语音听写可能会插入、替换或删除文本,而不会产生与物理键盘相同的
keydown 序列。
// Correct: responds to value changes regardless of input method
search.addEventListener('input', () => updateSuggestions(search.value));
// Wrong: dictation, paste, and autocomplete may bypass this logic
search.addEventListener('keydown', event => updateSuggestions(event.key));
文本输入控件应:使用原生输入框/文本区域;提供始终可见的标签;以编程方式提供格式说明和错误信息;支持粘贴、听写、自动补全和以编程方式更改值;允许在提交前编辑和更正;不设置过短的时间限制,也不假定特定的语速;在其他有效值也可接受时,不强制要求特定的标点短语;在验证出错后保留已输入的内容。不要因为没有 keydown 就推断没有发生输入——应在适当的事件中验证当前值,并在提交时再次验证。
严重:拖动、手势和空间交互需要直接替代方式
使用语音控制的指针进行拖动可能需要多条命令和精准的时机把控。
<li>
Budget report
<button type="button">Move up <span class="visually-hidden">Budget report</span></button>
<button type="button">Move down <span class="visually-hidden">Budget report</span></button>
</li>
如果也提供拖放功能,两种方式都应更新同一个模型并提供确认。对于滑块,应将可拖动控件与直接输入或步进控件配对:
<label for="volume">Volume</label>
<input id="volume" type="range" min="0" max="100" value="50">
<label for="volume-value">Volume percentage</label>
<input id="volume-value" type="number" min="0" max="100" value="50">
WCAG 2.5.7 要求作者创建的拖动操作提供单指针替代方式,除非拖动不可或缺——**仅键盘替代方式不一定满足这项单指针要求。**除非手势不可或缺,否则基于路径或多点触控的手势也需要根据 2.5.1 提供单指针替代方式。请参阅 skills/touch-pointer/SKILL.md。
中等:焦点、滚动和叠加层
一些语音用户会模拟键盘命令,或将语音与其他输入方式结合使用——焦点顺序、可见性以及控件不被遮挡仍然很重要。粘性页眉、Cookie 通知和聊天启动器不得遮挡已获得焦点的组件(WCAG 2.4.11)。
html { scroll-padding-block-start: var(--sticky-header-height, 4rem); }
:focus-visible { scroll-margin-block: 0.5rem; }
确保:焦点不会移到打开的模态框后面;关闭对话框后,焦点会返回到逻辑上合适的控件;直接激活时,必要情况下会将目标滚动到视野内;无需拖动或精准移动指针即可关闭叠加层;在支持的视口尺寸下,没有任何必要控件会被永久遮挡。语音输入可以与屏幕阅读器结合使用,因此交互不能依赖用户看见焦点或叠加层。
严重:以编程方式呈现状态、结果和错误反馈
<button type="button" aria-expanded="false" aria-controls="filters-panel">Filters</button>
<div id="filters-panel" hidden></div>
同时更新 aria-expanded 和 hidden——aria-pressed、aria-checked、选中的标签页和滑块值也应如此。
<p id="cart-status" role="status" aria-atomic="true"></p>
使用可见文本和适当的状态消息模式(请参阅
skills/aria-live-regions/SKILL.md)——不要为每条确认消息都移动焦点。对于需要立即更正的错误,应将错误与字段关联起来,并使用表单既有的错误摘要策略。避免以下反馈方式:仅通过颜色、动画或图标变化呈现;只能通过悬停查看;在用户来得及感知前就消失;对每个听写字符重复播报;对辅助技术 API 隐藏;与触发它的控件没有关联。
中等:标签、符号和本地化
可见标签和可访问名称应使用相同的自然语言——与界面的其余内容一同翻译 aria-label、隐藏上下文、描述和错误消息。不要将所有符号都规范化为无关的词语——正确名称取决于功能:用作控件的放大镜图标应命名为“搜索”,而不是“放大镜”;仅用作关闭图标的可见 X 应命名为“关闭”。应在每种受支持的界面语言和听写语言中测试语音匹配——在英语中有效的命令,翻译后可能无法使用。
产品和平台差异
语音工具在按名称激活控件、显示名称/数字/网格叠加层、区分重复名称、模拟键盘/指针输入、处理嵌入式框架和影子 DOM,以及切换命令/听写模式等方面各不相同。除非项目会主动维护并重新测试,否则不要将固定命令短语、产品版本或兼容性声明纳入项目标准。
记录实际测试环境:
Speech input product and version:
Operating system and version:
Browser and version:
Input and interface language:
Command, dictation, or mixed mode:
Viewport, zoom, and text size:
测试
- **静态检查:**识别可见标签;检查计算后的可访问名称/角色;确认可见文字完整且按顺序出现在名称中;检查可见短语之前或其中是否有隐藏文本;验证状态/值/描述之间的关联;确认能够区分重复控件;验证仅含图标的控件是否有简洁的名称;验证名称和隐藏文本是否已翻译。检查计算后的无障碍树——不要通过分别读取各属性来推断最终名称。
- 键盘基础测试(不使用指针):确保能够使用键盘访问和操作所有功能;遵循符合逻辑的焦点顺序;打开/使用/关闭自定义组件;退出对话框/菜单/弹出层;确认焦点始终可见且不被遮挡;完成拖动操作的替代方案。
- 语音输入测试(针对每种受支持的环境):使用该工具文档所述的语法,说出可见标签以激活带有可见标签的控件;检查工具的名称/数字叠加层是否便于发现;区分重复控件;操作仅含图标的控件和自定义组件;听写/编辑/替换/提交文本;触发并纠正验证错误;在模态框/菜单/标签页/展开面板/自动补全中导航;通过替代方案完成排序/重新排序/滑块/地图/画布任务;确认状态变更和状态反馈;在缩放/重排/本地化变更后重复关键任务。不要要求每个控件都响应同一个字面短语,例如“Click [label]”——应使用经过测试的工具所述语法。
- 邀请经常使用语音输入的用户参与测试——技术测试无法揭示纠正识别错误、区分控件或浏览密集叠加层所需的全部精力。
自动化检查可以检测缺少可访问名称的控件、某些可见标签与名称不匹配的情况、无效/缺失的角色/状态、非交互元素上的点击处理程序,以及重复的可访问名称;但无法判断语音产品是否确实能识别某个标签、重复控件在实际操作中是否容易区分,也无法判断命令总数是否会使任务难以完成。对于不确定的自动化结果,应将其视为待审查事项,而不是已确认的问题。
常见故障
| 故障 | 修正方法 |
|---|---|
| 可见的“Save”按钮,其隐藏名称为“Confirm changes” | 使用“Save”,或使用以“Save”开头的名称 |
| 在可见短语中插入隐藏词语 | 保持可见词语连续且顺序不变 |
| 每个重复链接的可见文本都是“Read more” | 使用具体的可见文本,或在其后追加相关的隐藏文本 |
| 占位符是唯一的字段标签 | 添加持久显示且与字段关联的 <label> |
| 仅含图标的按钮没有可访问名称 | 添加简洁的名称;优先使用持久显示的可见文本 |
| 将工具提示视为可见标签 | 当可发现性很重要时,让标签持续可见 |
使用样式化的 <div> 充当按钮 | 使用 <button>,或实现完整的自定义控件规范 |
仅在 keydown 时运行验证 | 响应 input、当前值和提交操作 |
| 只能通过拖放重新排序 | 添加“上移”/“下移”或位置控件 |
| 只能通过手势操作某项功能 | 为同一结果添加简单控件 |
| 固定内容遮挡获得焦点的控件 | 调整布局/滚动;在支持的尺寸下进行测试 |
| 状态变化仅体现为视觉变化 | 更新程序状态并提供可见反馈 |
| 项目文档承诺支持通用语音命令 | 测试并记录实际支持的产品和语言区域 |
| 测试假设所有语音用户都能看见 | 纳入非视觉和组合辅助技术的使用情形 |
完成标准检查清单
- 每个控件都公开准确的名称、角色、状态和值
- 每个可见文本标签都按原样、按顺序包含在可访问名称中
- 在可行时,可见文本出现在可访问名称的开头
- 在能够提供所需控件时使用原生 HTML
- 自定义控件遵循受支持的键盘和 ARIA 模式
- 无需重命名即可高效区分重复控件
- 仅含图标的控件具有简洁、本地化的可访问名称
- 表单字段具有可见且通过程序关联的标签(不能仅用占位符)
- 听写、粘贴、自动补全、编辑和更正都能正确更新字段
- 验证不只依赖物理按键事件
- 所有功能均可通过键盘界面使用
- 拖动和基于路径的手势均有单指替代操作
- 焦点顺序合理、清晰可见且不被遮挡
- 状态、验证错误、确认信息和结果均以程序化方式公开
- 在受支持的语音产品、浏览器和语言中测试关键任务
- 以手动语音输入测试补充自动化测试结果
关键 WCAG 标准
- 1.3.1 信息和关系(A)
- 2.1.1 键盘(A)
- 2.4.3 焦点顺序(A)
- 2.4.7 焦点可见(AA)
- 2.4.11 焦点未被遮挡(最低要求)(AA)
- 2.5.1 指针手势(A)
- 2.5.3 标签包含于名称中(A)——如果可见标签未包含在可访问名称中,则属于严重问题
- 2.5.7 拖动动作(AA)
- 3.3.2 标签或说明(A)
- 4.1.2 名称、角色、值(A)
- 4.1.3 状态消息(AA)
WCAG 标准描述的是结果,而非特定产品的语音命令——某条命令在某个环境中失效,可能表明内容存在缺陷、产品有所限制、本地化存在问题,或组合不受支持。在判定为标准不符合项之前,请记录环境并进行调查。
参考资料
**标准展望:**这些规则针对 WCAG 2.2 AA。 关注:https://www.w3.org/TR/wcag-3.0/