表单校验
核心不是"标红",而是什么时候报、报给谁看、焦点去哪。 这三件事决定了用户觉得表单"聪明"还是"烦人"。
一、校验时机:别在 oninput 报错
下面两个输入框规则完全一样,只有校验时机不同。都试着打几个字看差别。
反例:oninput 立即报错
刚敲下 1 就开始红了 —— 但 1 可能是合法的中间状态。
用户打到一半满屏红字,不敢继续打,甚至放弃填表。
这是纯噪音。
正例:blur 才首次校验
最多两位小数,例如 12.34
打字时安安静静。失焦那一刻才校验; 之后你回来修改才会实时提示(因为你已经知道它的规则了)。 这时才叫"帮助"而不是"指责"。
三层时机:
🔴 刻意没用
onblur 首次校验 → 之后才实时(字段"脏"过)→ onsubmit 全量校验并弹汇总。🔴 刻意没用
:has():它是 CSS Level 4,某项目 上 WebView 版本不确定,
而且把逻辑硬塞进样式层不可测。控制权交给 JS 加 data-dirty 属性。
第三种状态:异步校验中(field--checking)
正在检查是否可用…
🔴 校验中绝不能把输入框置灰或禁用 —— 用户会以为"不让打字了",
于是停在那里等,而其实他完全可以接着改。
正确做法只有一条:保持可输入,旁边给一个小的 pending 指示。
这个指示器是原地旋转(12px),不是全屏 spinner:
它只说明"这一项在查",不代表"整个页面在忙"。
prefers-reduced-motion 下放慢到 1.2s 但不停(停了会被当成卡死)。
二、完整表单:提交后出错误汇总
什么都不填,直接点提交。焦点会移到汇总上,汇总里每条可点击跳转。
三、错误文案:给建议,不给判断
反例
格式错误
非法输入
值不合法
WCAG 3.3.3 要求给修正建议。这三句用户读完还是不知道该改成什么。
正例
金额最多两位小数,例如 12.34
请填写公司名称,2 到 40 个字
这个日期在未来,请检查
每条都具体、可执行,还带一个正例。
四、无障碍要点
错误汇总:
role="alert" + 提交后焦点移到它 ——
否则屏幕阅读器用户不知道页面出现了新东西汇总里的条目用
<a href="#字段id">,
天然支持键盘和"复制链接",不要用 div onclick错误文案用
role="alert",
动态出现时会被读出来(aria-describedby 负责聚焦时能听到)提交成功后焦点必须移走 ——
留在提交按钮上,用户按 Enter 会重复提交