必须作用于可聚焦元素(如或tabindex="0"的<button>),不可用于<span>或禁用按钮;外层需role="navigation"/aria-label明确步骤条语义;焦点须匹配当前状态,禁用时用aria-disabled="true"而非仅视觉灰显。

aria-current 必须用在当前步骤的容器或链接上
很多开发者只给当前步骤加 aria-current="step",但忽略它必须作用于可聚焦元素(如 <a> 或带 tabindex="0" 的 <li>),否则屏幕阅读器无法感知上下文。如果当前步骤是纯 <span> 或禁用状态的按钮,aria-current 会失效。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 优先把步骤项写成语义化链接:
<a href="#step2" aria-current="step">填写信息</a> - 若不可跳转,改用
<button type="button" aria-current="step" tabindex="0">填写信息</button> - 避免套在父
<li>上——除非该<li>本身可聚焦且有明确角色(如role="link") - 不要同时设
aria-disabled="true"和aria-current="step",这会产生逻辑冲突
步骤条整体需有明确的 ARIA role 和 label
仅靠视觉样式(如数字、连线、颜色)无法传达流程结构。屏幕阅读器需要知道这是一个“步骤条”,且能获取总步数和当前位置。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 外层容器加
role="navigation"或更准确的role="progressbar"(适用于线性、不可逆流程) - 必须提供可访问名称:用
aria-label(如aria-label="注册流程:共4步,当前第2步")或关联<h2>+aria-labelledby - 若用
role="progressbar",还需同步设置aria-valuenow(当前序号)、aria-valuemin="1"、aria-valuemax(总步数) - 避免用
role="list"替代原生<ol>—— 原生有序列表自带序号语义,更轻量可靠
视觉焦点与键盘导航必须匹配当前步骤状态
用户用 Tab 键浏览时,焦点应自然停在可操作步骤上;当前步骤即使不可点击,也应能获得焦点(否则键盘用户会跳过它,破坏流程感知)。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 所有步骤项默认设
tabindex="0",再根据状态动态控制disabled属性或 CSSpointer-events: none(但不移除焦点能力) - 用 CSS 区分焦点样式:
:focus-visible要清晰可见,且不能仅依赖颜色(比如加边框+背景色双重提示) - 当前步骤若为只读态(如“已完成”),应通过
aria-disabled="true"明确声明,而非仅灰掉文字 - 避免用
display: none或visibility: hidden隐藏非当前步骤——这会让屏幕阅读器完全跳过,丢失上下文
辅助技术测试时容易漏掉的细节
自动化工具(如 axe)能捕获 aria-current 缺失,但测不出语义是否被正确消费。真实问题常出现在 NVDA/JAWS 的读屏节奏、VoiceOver 的滑动粒度,或键盘用户反复 Tab 后的迷失感。
关键检查点:
- 用 NVDA + Firefox 打开,按
D键跳到 landmark,确认能进入步骤条区域 - 逐个 Tab,听读屏是否报出“填写信息,当前步骤”或“步骤2,已完成”之类完整上下文
- 关闭 CSS 查看纯 HTML 结构:是否仍能通过顺序、文本和属性推断出流程逻辑?
- 移动端 VoiceOver 双指下滑时,是否把每个步骤作为独立 item 朗读,而不是连成一整段?
最常被忽略的是:当前步骤的视觉高亮没同步更新 aria-label 文本(比如界面上显示“第2步:填写信息 ✅”,但 aria-label 还是“第2步:填写信息”),导致读屏无法传达完成状态。



















