表单在视觉稿里通常很简单:标题、几个输入框、一个按钮。真正用起来却有很多状态,空值、格式错误、网络等待、服务端拒绝都要表达。可访问性检查并不是额外装饰,它常常会顺手提升所有人的使用体验。

每个输入都能说清“这是什么”

占位文字不能代替 label。用户输入后占位就消失,记忆负担会变大;屏幕阅读器对它的处理也不等同标签。最稳妥的写法仍然是可见标签,用 for 和输入框的 id 关联。

有格式要求时,说明文字放在输入附近,并用 aria-describedby 关联。这样说明不是视觉上“挨着”而已,辅助技术也能知道两者的关系。必填状态除了星号,还应该有文字或原生 required

把鼠标放到一边,按一次 Tab

我会从页面顶部开始只用键盘完成整张表单。焦点顺序是否符合阅读顺序?每个控件有没有清楚的焦点样式?自定义下拉能否用方向键和 Escape?如果普通 HTML 元素已经能满足需求,优先保留原生行为。

不要用 outline: none 删除焦点环,除非同时提供一个同样清楚、对比度足够的替代样式。

Tab 顺序一般应由 DOM 顺序自然决定。用正数 tabindex 人工调整很容易在页面变化后失控。若视觉顺序和 DOM 顺序完全不同,更值得回头检查布局结构。

错误不能只变红

提交失败时,输入框边框变红只对一部分人有效。错误文案要说明发生了什么以及怎么修,例如“密码至少需要 8 个字符”,而不是笼统的“格式错误”。输入框使用 aria-invalid="true",并把错误文案的 id 加入 aria-describedby

长表单可以在顶部增加错误摘要,提交后把焦点移到摘要,再提供跳转到具体字段的链接。短表单至少要把焦点放到第一个错误字段,否则键盘用户可能不知道页面哪里发生了变化。

告诉用户系统正在做什么

点击提交后可以暂时禁用按钮防止重复,但按钮文字最好变成“正在保存…”,页面上再用一个状态区域宣布结果。请求失败时保留用户已填内容,不要让一次网络波动变成重新填写。

十分钟清单:可见标签;合理输入类型;键盘可达;焦点清楚;错误有文字;状态会宣布;缩放到 200% 仍能使用。

最后我还会在手机尺寸和浏览器放大状态下检查一遍。很多看似无障碍的问题,其实也是触摸目标太小、文案换行后遮挡、软键盘类型错误这些日常可用性问题。把表单当成一段完整对话,而不只是几个方框,细节会自然很多。

← 上一篇下一篇:AI 补测试 →