只用form-field--invalid,因其是唯一需JS主动控制的修饰符,挂载于字段容器上以驱动label、input、error等关联样式;form-field--valid易致语义误判和视觉错乱,form__input--error等写法违反BEM封装原则且无法同步控制周边元素。

表单验证状态只能用 form-field--invalid 一个修饰符,挂载在字段容器上;其他所有变体(如 form-field--valid、form__input--error)都是误用,会破坏语义、干扰无障碍、引发视觉错乱。
为什么只用 form-field--invalid 而不用 form-field--valid
验证状态天然互斥,但 form-field--valid 容易触发语义误判:用户刚输入邮箱,JS 立刻加这个类,可此时表单根本没提交,后端还没校验,业务逻辑上它并不“有效”。更现实的问题是视觉错乱——空字段初始就被 :valid 触发绿色边框;或输入后立刻变绿,提交失败又跳红,用户信任直接崩塌。
只保留 form-field--invalid 作为唯一 JS 主动控制的类,意味着:
- JS 校验返回
false时添加,返回true或undefined时移除 - 初始态不依赖任何修饰符,靠
.form-field__input:not(:placeholder-shown)或form-field--touched区分是否已输入 - 如需密码强度等实时确认,可用
form-field--touched form-field--valid组合,但form-field--valid绝不能单独出现
form-field--invalid 必须挂在字段容器上,不能挂 input 或 form
常见错误是把类加在 input 上,比如 form__input--error。这违反 BEM 原则:Element(__input) 不能带 Modifier(--error),且样式只能作用于 input 自身,无法同步控制 label 颜色、错误文案显隐、icon 状态等关联行为。
立即学习“前端免费学习笔记(深入)”;
正确结构是让修饰符落在字段级 Block 容器上:
<div class="form-field form-field--invalid"> <label class="form-field__label">邮箱</label> <input class="form-field__input"> <div class="form-field__error">请输入正确的邮箱地址</div> </div>
CSS 通过后代选择器统一驱动:
-
.form-field--invalid .form-field__input控制边框 -
.form-field--invalid .form-field__label控制颜色 -
.form-field--invalid .form-field__error控制显隐
禁止挂在 form 元素上——否则一个字段错,整表单变红,用户无法定位具体问题。
哪些写法属于典型误用,必须避免
以下类名看似合理,实则破坏 BEM 封装与状态语义:
-
form-field--valid:无明确校验上下文时,它不代表业务有效,仅表示格式合规,但用户尚未提交,不应提前反馈“成功” -
form__input--error:把状态挂到 Element 层级,无法联动 label 和 error 文案,且违反__element不得带--modifier的规则 -
form--invalid:修饰符落在顶层 Block,导致整个表单失去字段粒度,无障碍属性(如aria-invalid)无法精准绑定 -
form-field__error--visible:错误文案的显隐应由父容器状态驱动,而非自身加修饰符,否则 JS 需重复管理两套状态
真正需要区分的不是“错误类型”,而是“错误是否已触发”——这个信号必须由单一、可预测的容器类承载,其余都靠内容文本和 CSS 后代选择器响应。


















