多步确认界面无障碍问题需从流程起点控制焦点流和语义结构:切换步骤后须主动 focus() 到新步骤标题或首字段,配合 aria-live 更新文本并设 aria-atomic="true",用 aria-current="step" 标记当前步骤,按钮须原生且同步 disabled 与 aria-disabled。

多步确认界面的无障碍问题,核心在于焦点丢失、状态不可感知、跳转逻辑混乱——不是加几个aria-live就能解决,得从流程起点就控制焦点流和语义结构。
多步表单中焦点为何总“消失”?
用户点“下一步”后,焦点没落到新步骤的首个可操作元素上,键盘用户卡在空白处;或模态层打开后焦点仍留在背景页,读屏直接跳过整个新步骤。
- 根本原因:JavaScript 跳转后未主动
focus()到新步骤容器或首字段,尤其用display: none/visibility: hidden切换步骤时,隐藏元素仍保留在 tab 顺序中 - 正确做法:切换步骤后,立即将焦点设到
step-2的h2(用tabindex="-1"临时聚焦)或首个input,同时确保该元素不在aria-hidden="true"区域内 - 别踩坑:用
scrollIntoView()代替focus()——滚动不等于聚焦,键盘用户依然无法输入
aria-live 在多步确认里为什么没反应?
设置了 aria-live="polite",但屏幕阅读器根本不播报“已进入第二步”,或错误提示延迟数秒才读出。
- 关键限制:
aria-live只监听 DOM 子树的文本变化,不监听display或visibility切换;若新步骤内容是通过 JS 注入且未触发 textContent 更新,它就“看不见” - 可靠写法:在插入新步骤 HTML 后,立即更新一个
aria-live区域的textContent,例如:<div aria-live="polite" aria-atomic="true" class="sr-only"></div>
然后liveRegion.textContent = "正在填写收货信息,请输入姓名和电话" -
aria-atomic="true"必须配对使用,否则只读变化部分,可能漏掉关键动词(如把“请检查订单”读成“检查订单”)
步骤标题与当前状态如何被屏幕阅读器准确识别?
读屏报出“步骤 1”,但用户实际在第三步;或反复播报“请填写”,却没说明这是第几步、共几部、哪步已完成。
- 必须用
aria-current="step"标记当前激活步骤的标题,例如:<h2 aria-current="step">确认订单</h2>,读屏会明确读作“确认订单,当前步骤” - 步骤导航条需用
role="navigation"+aria-label="表单步骤导航",每个步骤项用aria-disabled="true/false"和aria-label补充状态,如:<span aria-disabled="true" aria-label="收货地址,已完成">1</span> - 避免仅靠视觉样式(颜色、图标)表达状态——读屏无法感知“灰色=已完成”,必须有对应 ARIA 属性或文本
“返回”和“提交”按钮的键盘操作为何失效?
Tab 键跳过“返回”按钮,或按空格键无响应;更糟的是,提交失败后按钮仍 disabled,但没同步更新 aria-disabled,读屏还当它是可操作的。
- 所有按钮必须是原生
<button></button>,禁用时设disabled+aria-disabled="true"(双保险,因某些读屏忽略纯disabled) - “返回”按钮需确保在 tab 顺序中紧邻上一步内容之后,不要用
tabindex="1"强行插队——会打乱自然流 - 提交失败后恢复按钮状态时,必须同时移除
disabled属性和aria-disabled,否则读屏仍播报“不可用”
多步确认最易被忽略的点:步骤切换时未重置 aria-invalid 和 aria-describedby 的关联,导致旧错误消息仍被读出;以及未在每步开头提供简短语音摘要(如“第二步:支付方式,请选择银行卡或支付宝”),仅靠标题不够。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











