无障碍表单

共 17 题
📑 题目列表 17 题
#
★★★

1. aria-required/aria-invalid 在错误状态可访问描述的工程价值

请说明 aria-required 与 aria-invalid 在表单错误状态可访问描述中的工程价值?

  • aria-required 的作用
  • aria-invalid 的值与错误标记
  • 与原生属性的关系

aria-required(或原生 required)标记必填字段,让读屏告知用户"该字段必填"。aria-invalid 标记字段校验失败(值 true 表示无效,可加 aria-invalid="spelling"/"format" 等细分),让读屏与浏览器标记错误状态。工程价值:二者配合实现"错误状态可感知"——比视觉红框更关键的是读屏能宣布"必填"与"无效"。优先用原生 required(浏览器自动映射到 aria-required),aria-invalid 需在校验失败时设置、成功时清除(设 false 或移除)。注意:aria-invalid 是"状态"而非"样式",需配合视觉样式与错误文字一起呈现。

表单错误无障碍的关键是"让读屏用户知道哪个字段必填/无效"。原生 required 优先,aria-invalid 动态管理状态,才能让错误状态同时被视觉与读屏感知。

#
★★★

2. aria-describedby/aria-errormessage 在表单错误信息关联的工程价值

请说明 aria-describedby 与 aria-errormessage 在表单错误信息关联中的工程价值?

  • aria-describedby 关联描述
  • aria-errormessage 关联错误
  • 两者的区别与使用

aria-describedby 把表单控件与描述性内容(帮助文字、错误提示、格式说明)关联,读屏聚焦控件时会播报这些内容;aria-errormessage 专门关联错误信息元素,且必须配合 aria-invalid="true" 才生效,用于精准关联"字段对应的错误提示"。工程价值:二者让"错误/帮助与字段"建立可读屏感知的关联,避免用户不知道错误属于哪个字段。区别:aria-describedby 可关联多种描述(帮助+错误),aria-errormessage 只关联错误且需 invalid 触发。实现时错误信息元素需可被定位(id 稳定),插入/更新时配合 live region 播报。

表单正确性极大依赖"错误与字段的关联"。aria-describedby 通用、aria-errormessage 精准且需 invalid 配合。理解二者分工能实现"错误定位 + 播报"的完整无障碍。

#
★★★

3. ARIA live region 与 aria-describedby 在表单错误提示的协作

请说明 ARIA live region 与 aria-describedby 在表单错误提示中如何协作?

  • live region 的播报作用
  • aria-describedby 的关联作用
  • 两者的协作

二者协作实现"错误被播报 + 错误被关联"。aria-describedby 把错误文字与对应字段关联,读屏聚焦字段时读到错误;live region(如 role="alert")在错误出现时主动播报,让用户无需聚焦也能听到"提交失败/有 N 个错误"。工程实践:表单提交后在错误汇总区(role="alert")播报错误数量,同时每个字段用 aria-describedby 关联其具体错误;可把焦点移到第一个错误字段以帮助定位。注意避免重复播报(aria-describedby 与 live 同时播报同一错误可能重复),需设计好播报边界。

live region 负责"主动告知",aria-describedby 负责"聚焦时关联",两者互补。加上"焦点移到第一条错误"形成完整策略。协调好播报时机避免重复,是工程细节。

#
★★

4. 表单验证的无障碍反馈,aria-live 与错误关联?

请说明表单验证的无障碍反馈如何实现,包括 aria-live 与错误关联?

  • 验证反馈的读屏实现
  • aria-live 播报
  • 错误与字段关联

表单验证的无障碍反馈包括:一是错误播报——用 aria-live(role="alert")在验证失败时播报错误汇总,让读屏用户立即知道;二是错误关联——每个无效字段用 aria-invalid 标记,并用 aria-describedby/aria-errormessage 关联具体错误文字;三是焦点管理——提交失败后把焦点移到第一个错误字段,或聚焦错误汇总,帮助用户定位;四是视觉反馈——错误文字、边框、图标需满足对比度且不单靠颜色。三部分(播报、关联、焦点)协作,才能让读屏用户完整理解"哪里错了、错在哪、怎么改"。

表单验证是"错误反馈"的完整场景。仅视觉红框对读屏用户无效,必须通过 aria-live 播报 + aria-invalid/describedby 关联 + 焦点管理三管齐下,这是无障碍表单的成熟实践。

#
★★

5. 自定义滑块(range)等复杂控件的无障碍,role=slider、aria-valuenow/valuetext、方向键操作与读屏播报如何实现?

请说明自定义滑块(range)等复杂控件的无障碍实现,包括 role=slider、aria-valuenow/valuetext、方向键操作与读屏播报?

  • role="slider" 与值属性
  • aria-valuetext 的可读文本
  • 方向键操作

自定义滑块用 role="slider" + aria-valuenow/valuemin/valuemax 表达数值范围,用 aria-valuetext 提供可读的当前值文本(如"亮度 50%"),用 aria-orientation 表达方向。实现方向键操作:监听 ArrowUp/Down/Left/Right、PageUp/PageDown、Home/End 调整值,焦点保持在滑块上;调整为浮点数时可设 aria-valuetext 精确值。读屏播报:焦点在滑块上时聚焦读 aria-label,值变化时读屏读 aria-valuetext。若无特殊需求,优先用原生 <input type="range">(自带全部语义与键盘)。

Slider 无障碍的核心是"值变化可读屏感知 + 键盘可调 + 焦点不跳动"。原生 range 已覆盖,自定义时需完整实现 aria 值属性与方向键。这是复杂控件无障碍的典型范例。

#
★★

6. label 关联、错误提示 aria-describedby、required、aria-invalid

请说明表单控件中 label 关联、错误提示 aria-describedby、required、aria-invalid 的正确使用?

  • label 的关联方式
  • aria-describedby 错误提示
  • required 与 aria-invalid

每个表单控件都应有 label 关联:用 <label for> 或包裹式 label,或用 aria-label/aria-labelledby(无可见 label 时)。错误提示用 aria-describedby 关联描述文字,帮助与错误可同时关联。必填用原生 required(自动映射 aria-required),校验失败用 aria-invalid 标记。正确组合:label 提供名称、aria-describedby 提供错误/帮助、required + aria-invalid 表达必填与无效状态。注意 aria-describedby 关联的元素 id 必须存在,错误出现时才设置(避免在错误文字存在前就关联)。

这四个点构成"表单控件无障碍"的完整骨架:name(label)、description(describedby)、required state、invalid state。正确组合让读屏能说出"标签+必填+错误+帮助",是表单无障碍的基础。

#
★★

7. autocomplete=one-time-code/inputmode=numeric 在 OTP/数字键盘输入的工程价值

请说明 autocomplete="one-time-code" 与 inputmode="numeric" 在 OTP/数字键盘输入中的工程价值?

  • autocomplete="one-time-code" 的作用
  • inputmode 的键盘类型
  • OTP 输入的落地

autocomplete="one-time-code" 让浏览器/iOS 能自动识别短信验证码(OTP)并填充,极大提升输入体验;inputmode="numeric" 提示移动端弹出数字键盘,适合纯数字输入(如验证码、PIN)。工程价值:OTP 输入通常用多个单字符输入框组合,需用 aria-label 命名每个框、用 aria-describedby 关联说明、处理自动填充值分发到各框。输入框用 inputmode 而非 type="number" 可避免 number 的滚动/步进问题。整体降低"一次性验证码"场景的输入成本与出错率。

这是"移动端输入体验 + 无障碍"的结合。autocomplete 让验证码自动填充(读屏用户也能受益),inputmode 优化键盘,二者配合能显著降低 OTP 场景的障碍。

#
★★

8. 可访问的日期选择器与复杂控件

请说明可访问的日期选择器与复杂控件的实现要点?

  • 日期选择器的结构
  • 键盘交互
  • 焦点管理

可访问日期选择器通常用 role="dialog" 或 grid(日历网格)实现,提供:文本输入框(可手动输入日期,并用 aria-label 命名、格式说明)、日历网格(role="grid" + 单元格)、上一月/下一月按钮、确认/取消。键盘交互:方向键在日期间移动、Enter 选择、Esc 关闭、焦点管理(打开时聚焦日期或输入框,关闭后归还)。应提供直接输入作为视觉日历的替代(因为弹层日历对读屏和键盘复杂)。复杂控件普遍遵循:原生优先 + 简单替代方案 + 完整键盘/焦点管理。

日期选择器是"复杂控件"的代表,APG 用 grid 模式实现。关键不是日历本身,而是"提供手动输入替代 + 完整键盘/焦点管理"。这是复杂控件无障碍的核心思路。

#
★★

9. 表单字段的分组与描述,fieldset/legend、aria-labelledby 在多控件分组中的正确用法?

请说明表单字段分组与描述,包括 fieldset/legend 与 aria-labelledby 在多控件分组中的正确用法?

  • fieldset/legend 的语义
  • aria-labelledby 分组
  • 多控件分组场景

一组相关的表单控件(如"联系方式"里的多个输入、单选按钮组)应用 fieldset + legend 分组:fieldset 是分组容器,legend 提供组标题,读屏聚焦组内控件时会播报组名。当无法用 fieldset(如自定义结构)时,可用 role="group"(或 radiogroup)配合 aria-labelledby 指向组标题元素来提供分组语义。aria-labelledby 的优先级高于 aria-label,可指向任意元素。正确用法:能用 fieldset/legend 就用;用 aria-labelledby 时确保指向的元素有可见文本;单选组用 role="radiogroup" 表达。

分组让读屏理解"哪些控件属于同一组"。fieldset/legend 是原生方案,aria-labelledby 是 ARIA 替代。理解何时用哪种、以及 aria-labelledby 的优先级,是分组描述的关键。

#
★★

10. 键盘可达性,Tab 顺序、焦点可见性(focus-visible)、Enter/Esc 交互在自定义控件中的实现?

请说明自定义控件中键盘可达性的实现,包括 Tab 顺序、焦点可见性(focus-visible)、Enter/Esc 交互?

  • Tab 顺序控制
  • focus-visible 焦点指示
  • Enter/Esc 交互

自定义控件键盘可达性四要素:1)Tab 顺序——用 tabindex=0 让控件可聚焦并按序进入,避免正值打乱顺序;2)焦点可见性——用 :focus-visible 提供键盘操作时的清晰焦点环,:focus 保证鼠标也不丢失,避免 outline:none 裸删;3)Enter——模拟按钮按 Enter 触发操作(原生 button 自动支持,自定义需实现);4)Esc——用于退出弹层/菜单/取消操作,自定义控件需监听并实现。这些让自定义控件与原生控件在键盘上等价,是"ARIA 语义 + 行为"的要求。

"用了 ARIA 就必须实现行为"——键盘行为是 ARIA 语义的配套。Tab 顺序、focus-visible、Enter/Esc 是自定义控件键盘可达性的完整清单,缺一不可。

#
★★

11. 表单的键盘可达性,焦点管理与错误提示?

请说明表单的键盘可达性,包括焦点管理与错误提示?

  • 表单 Tab 顺序
  • 焦点管理(错误定位)
  • 错误提示的读屏

表单键盘可达性:Tab 顺序应遵循逻辑顺序(字段从上到下、相关控件分组),焦点可见性用 focus-visible。错误提示的键盘可达性:提交失败后把焦点移到第一个错误字段(或错误汇总),让键盘用户知道"哪里错了";错误字段用 aria-invalid + aria-describedby/aria-errormessage 关联具体错误;用 live region 播报错误汇总。焦点管理要避免"焦点跳走后又跳回"的混乱,错误修复后清除 aria-invalid 并处理焦点。整张表单所有操作(提交、选择、清除)都应仅用键盘完成。

表单键盘可达性 = 合理 Tab 顺序 + 焦点管理 + 错误提示。焦点管理尤其关键——错误后不移动焦点,键盘用户会在表单里"迷失"。这是表单无障碍的工程重点。

#

12. 表单验证失败的可访问反馈

请说明表单验证失败的可访问反馈如何实现?

  • 错误播报
  • 错误关联
  • 焦点与视觉反馈

表单验证失败的可访问反馈包括:1)播报——用 aria-live(role="alert")播报"有 N 个验证错误";2)关联——每个无效字段用 aria-invalid 标记,用 aria-describedby/aria-errormessage 关联具体错误文字;3)焦点——把焦点移到第一个错误字段或错误汇总,帮助定位;4)视觉——错误文字、边框、图标有足够对比度,且不单靠颜色(配图标/文字)。避免重复播报:描述与 live 播报协调,防止同一错误被读两次。完整反馈让读屏用户能"听到错误、定位字段、理解错误"。

验证失败反馈是"错误信息传达"的完整案例。四要素(播报、关联、焦点、视觉)协同,才能让所有用户(包括读屏/键盘)获得等价的错误信息。

#

13. 无障碍表单的自动化测试,axe-core 扫描 + 键盘导航模拟如何纳入 CI?

请说明无障碍表单的自动化测试如何纳入 CI,包括 axe-core 扫描与键盘导航模拟?

  • axe-core 表单扫描
  • 键盘导航模拟
  • CI 集成

无障碍表单自动化测试纳入 CI 分两层:1)axe-core 扫描——用 axe-core(或 @axe-core/playwright、cypress-axe)在 E2E 测试中扫描表单,自动检查 label 缺失、aria-invalid 使用、对比度等,规则可配 wcag2a/wcag2aa 等;2)键盘导航模拟——用 Playwright/Cypress 模拟 Tab/Enter/Esc 键,断言 Tab 顺序、焦点位置、错误提示的 aria 属性、焦点是否移到第一个错误字段。把这些测试加入 CI 即可在每次提交时自动发现回归。表单专项测试应覆盖:必填、错误态、焦点管理、错误播报。

axe 扫描捕获"静态规则"问题,键盘模拟捕获"行为/焦点"问题,二者互补。纳入 CI 是保证无障碍不退化的关键工程手段,尤其对表单这类高频交互。

#

14. 屏幕阅读器适配,label、aria-describedby 的使用?

请说明屏幕阅读器适配中 label 与 aria-describedby 的使用?

  • label 的读屏作用
  • aria-describedby 的描述
  • 读屏朗读顺序

读屏适配表单控件:label 提供控件名称,读屏聚焦时先读 label(可为 text via for 或包裹式),无 label 的控件用 aria-label/aria-labelledby 提供名称。aria-describedby 提供额外描述(帮助文字、错误提示),读屏会在名称之后播报描述。读屏朗读顺序:名称(label)→ 描述(describedby)→ 状态(state)。工程上:所有可见控件用 label 关联,帮助/错误用 aria-describedby,避免把"标题"当 label 用(label 必须与控件关联,语义才正确)。保持读屏播报简洁,避免冗长描述。

读屏适配的核心是"名称 + 描述 + 状态"的完整语义。label 是名称,aria-describedby 是描述,二者协作让读屏用户获得与视觉用户等价的表单信息。

#

15. 复杂控件(日期选择器)的无障碍实现?

请说明复杂控件(如日期选择器)的无障碍实现要点?

  • 结构语义
  • 键盘导航
  • 焦点管理

复杂控件(日期选择器)无障碍实现:1)结构——用 role="grid"(日历网格)或 dialog,提供 aria-label 命名(如"选择日期")、aria-describedby 格式说明;2)键盘——方向键移动日期、Enter 选择、PageUp/Down 翻月、Esc 关闭;3)焦点——打开时聚焦当前日期或输入框,关闭后归还焦点;4)替代——提供手动输入框(可输入日期文本)作为弹层日历的替代,因为弹层对读屏/键盘复杂;5)关联——输入框与弹层用 aria-controls/aria-expanded 关联。整体遵循"原生优先 + 简单替代 + 完整键盘/焦点"。

日期选择器是无障碍复杂的缩影。核心思路是"提供简单替代方案(手动输入)+ 弹层完成键盘与焦点管理"。强调替代方案是因为复杂弹层对部分用户反而更困难。

#

16. 表单的无障碍测试,键盘与读屏验证?

请说明表单的无障碍测试方法,包括键盘与读屏验证?

  • 键盘测试
  • 读屏测试
  • 测试覆盖范围

表单无障碍测试分键盘与读屏两类。键盘测试:用 Tab 走遍表单,验证顺序正确、焦点可见、Tab 不出逃/不被困、Enter 提交、Space 切换、错误后焦点移到第一个错误字段。读屏测试:用 NVDA/VoiceOver 走一遍,验证 label 被播报、错误提示通过 aria-describedby/aria-live 播报、必填与无效状态被宣布、各组关系(fieldset/legend)正确。自动化部分用 axe 扫描 + Playwright 键盘模拟,人工部分用读屏验证。覆盖场景:正常填写、必填缺失、格式错误、重复提交等。

键盘测试验证"可操作",读屏测试验证"可感知"。二者人工/自动化结合,才是表单无障碍的完整验证。键盘测试相对可自动化,读屏测试需人工但最关键。

#

17. 表单校验失败后的焦点与通告策略,focus 到第一条错误字段、aria-live 错误汇总与防止读屏重复播报的边界?

请说明表单校验失败后的焦点与通告策略,包括 focus 到第一条错误字段、aria-live 错误汇总与防止读屏重复播报的边界?

  • 焦点应到第一条错误字段
  • aria-live 错误汇总
  • 防止重复播报

校验失败后的策略:1)焦点——把焦点移到第一个错误字段(或错误汇总),让键盘/读屏用户从错误起点开始;2)通告——用 aria-live(role="alert")播报错误汇总(如"有 3 个错误"),让用户立即知道提交失败;3)关联——每个无效字段用 aria-invalid + aria-describedby 关联具体错误。防止重复播报的边界:焦点移到第一个错误字段时,读屏会读该字段的 label 与 describedby 错误;若同时用 live 播报同一错误,会产生重复。因此通常 live 只播报"错误汇总/数量",具体错误靠聚焦字段时读,避免同一错误被读两次;或 live 用 role="alert" 播报摘要,字段错误用 describedby 聚焦时读。

焦点定位 + 汇总播报 + 字段关联三者的紧密结合,最大的坑是"重复播报"。设计上让"live 播报汇总、聚焦读具体错误"分工,即可平衡"及时告知"与"不重复轰炸"。