H1.14.3dynamic fields disrupt screen-reader order设计研究

动态显隐会打乱屏幕阅读器的线性朗读顺序

别名: 显隐与朗读顺序 · live region form · SR order jump

概念解释

屏幕阅读器按无障碍树的线性顺序往下读。条件字段在树中间插入或删掉节点,朗读头可能停在已经消失的控件上,或跳过新插入的块,下一次 Tab 落到视觉上不相邻的项。打乱线性顺序指的是这条朗读/焦点故事不再与视觉故事重合。可视用户的「突然出现」是空间问题;阅读器用户的问题是插入点、焦点和播报。字段还交不交、规则好不好维护,不是这里的重点。

机制

阅读器有两种走法:浏览模式沿文档走,焦点模式沿 Tab 走。动态插入若只改了视觉布局、没插进正确的树位置,浏览模式会在旧位置读到空白,焦点模式会按 DOM 落到远处。第二层是插入时焦点还在触发控件上:人按空格勾选「需要发票」,焦点仍在复选框,新字段出现在下方却没有任何宣布。没有活区域,插入等于没发生;活区域太吵,又会把正在听的标签打断。删掉当前焦点所在节点时,阅读器会把焦点弹到文档顶端或邻近的随机节点,人丢失上下文。正确的顺序修补是:节点插在触发控件之后、插入后宣布新增了什么、删除前先把焦点移到还存在的触发控件。

怎么研究

用至少一种主流阅读器走条件表:勾选后听朗读,再 Tab。比较无宣布、用 aria-live 宣布、插入后把焦点移到新字段。

自变量:插入在树中的位置、是否宣布、删除时焦点是否先挪走、浏览模式还是焦点模式。 因变量:新字段是否被读到、焦点落在已删除节点的次数、从触发到新字段的 Tab 次数、人能否说出「刚多了什么」。

不同阅读器对 live 区域和焦点回退的实现差很大,至少测两套(例如桌面 + 移动)。不要用可见性动画是否平滑来代替朗读检查。

边界

一次插入大量字段(选了企业之后出现十项),逐项宣布会变成噪声,应宣布「已增加企业信息一节」再让人自行 Tab 进去。纯装饰性的显隐(多显示一句提示、没有新输入)用礼貌的 live 即可,不必移焦点。阅读器用户若正在该字段输入,不要因为另一个条件变化把焦点抢走。打印和只读归档没有朗读顺序问题。

怎么落地

  • 把条件节点插在无障碍树里触发控件的后面,而不是追加到表单末尾或一个远离的容器。
  • 插入后用简短 live 宣布新增了什么;不要在人还在触发控件上时把焦点强行塞进新字段,除非新字段是唯一必须立刻回答的项。
  • 删除当前焦点所在字段之前,先把焦点送回触发控件,再移除节点。
  • 验证:开阅读器勾选条件,确认听到新增块的名称,Tab 一次落到该块的第一项而不是页脚。删掉焦点所在的条件字段,确认焦点回到触发控件而不是文档顶。把新字段插到 DOM 末尾作为反例,确认朗读故事与视觉故事分裂。

延伸

  • 同组H1.14.1 条件字段的显隐规则需对用户可预期,不能突然消失或新增 · H1.14.2 已填内容的字段被隐藏时需明确其数据是否仍会提交 · H1.14.4 过多层级的条件分支会让表单逻辑难以调试与维护
  • 相邻J5.12 动态内容的播报 · J2.08 阅读顺序 · H1.15 表单的可访问性标注
  • 站内检索aria-live · screen reader · focus restoration

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/H1.14.3