input · 五态矩阵

输入框取五态,不是七态——input 没有 active 态,输入框不响应按压。

与 button 最关键的一处不同: button 用 :focus-visible(鼠标点击不冒框), input 用 :focus(用户必须随时知道光标在哪)。 搞反了表单会非常难用。自己 Tab 一遍下面的输入框就能体会。

五态

1. hover

边框加深。鼠标移上来。

2. focus

边框变 accent + 外圈 ring。点进去或用 Tab 切过来。

3. disabled

不可聚焦、值不提交。试着 Tab 过去——跳过的。

4. readonly

可聚焦、可以选中复制、值会提交。Tab 能到,试试复制这段字。

5. error

红边框 + 叹号图标 + 错误文字,三条线索。不只靠颜色。

请输入有效金额

带说明

aria-describedby 把说明挂到输入框,聚焦时屏幕阅读器会一起读出来。

最多两位小数

尺寸与布局:小尺寸 / 多行 / 标签在左

这三档不是"好看的选项",是三种不同的约束: 密度(表格行内)、行数(会换行的说明)、方向(标签在左的表单)。 写错哪一个都是"内容被裁掉"或"标签跑到控件上面"。

field__input--sm

视觉 36px、命中区仍 44px(min-height 兜底)。用在表格行内、侧栏这类密度高的地方。

field__input--textarea

直接拿 .field__input 配 <textarea> 会被 44px 固定高度裁掉。这一档放开高度、留 88px 起,并允许纵向拉伸。

field--row

标签在左、控件在右,标签宽度固定 88px ⇒ 一列输入框的起点能对齐。480px 以下自动回退纵向。

对比:常见写法 vs 本库写法

常见写法

placeholder 当 label —— 一输入就消失
只把边框变红 —— WCAG 1.4.1 禁止只靠颜色传达信息
font-size: 14px —— iOS Safari 会自动放大整个页面
错误文字没有 aria-describedby —— 屏幕阅读器读不到

本库写法

请输入有效金额

有可见 label,不会消失
红边框 + 图标 + 文字,三条线索
font-size: 16px —— iOS 不缩放
role="alert" + aria-describedby —— 会被读出来

交互演示:校验

这里是分层校验:逐个输入试,每种错误会得到各自对应的提示。 1111aaa → 「只能输入数字」· 12.345 → 「最多两位小数」· 1.2.3 → 「只能有一个小数点」。
🔴 原来的实现只有一条正则 + 一句固定提示,于是不管输入什么都说「最多两位小数」—— 提示与实际错误对不上,用户根本不知道该改什么。

最多两位小数,留空点校验试试

iOS 那条 16px 不是审美

iOS Safari 在输入框 font-size < 16px 时,用户一聚焦就自动放大整个页面, 而且不会自动缩回去。用户会以为页面坏了。

这是移动端最常见的表单 bug,也是本库把 input 字号钉死在 16px 的唯一原因。 紧凑场景用 --sm(36px 高)但字号仍然是 16px。