必须挂到字段级 block 容器上,如 field-email;挂错位置会导致反馈失控、复用困难、无障碍失效;field-email--invalid 修饰符统一控制输入框边框、错误文案显隐及 label 颜色。

表单验证状态该挂哪个 DOM 节点上
必须挂到字段级 block 容器上,比如 field-email,而不是 form__input 或整个 form。挂错位置会导致校验反馈无法精准控制、复用困难、无障碍支持失效。
-
field-email--invalid这类修饰符作用于容器,CSS 里统一控制field-email__input边框、field-email__error显隐、field-email__label颜色 - 若挂到
form__input--invalid,JS 就得同步操作 label 和 error 元素,容易漏掉或顺序错乱 - 挂到
form--invalid更糟:一个字段出错,整表单变红,用户根本找不到问题在哪
多个校验规则共存时怎么命名修饰符
不要堆砌 field-email--empty--format--domain,这种写法会让 CSS 权重失控、JS 切换逻辑爆炸、无障碍属性难同步。
- 统一用单一语义状态修饰符:
field-email--invalid,错误文案由field-email__error的 innerText 决定,不是靠 class 名 - 若需区分错误类型(如空值 vs 格式错),用 JS 动态更新
aria-describedby指向不同 ID,而非靠 class 区分视觉样式 - 禁用
field-email--js-invalid这类带实现细节的修饰符——CSS 不该知道校验是用正则还是 API 返回的
:valid/:invalid 伪类为什么不能替代 JS 控制
浏览器原生伪类在多数关键场景下不触发,纯靠它做验证反馈等于放弃控制权。
-
:invalid对空必填字段不生效,除非用户已聚焦并失焦(touched),但设计要求“初始为空就显示浅灰边框+提示文字” -
:user-invalid在 iOS Safari 上支持极差,连基础邮箱格式错都常不响应 - 校验逻辑常依赖异步(如用户名是否已存在),伪类完全无法介入
- 最终状态必须由校验函数返回值驱动,
field-email.classList.toggle('field-email--invalid', !isValid)才可靠
label 和 input 的 DOM 关系怎么确保语义对齐
BEM 类名再规范,如果 HTML 结构没对齐,屏幕阅读器、自动化检测、甚至 :focus-within 都会失效。
- 推荐显式
for/id绑定:<label for="field-email__input"></label>+<input id="field-email__input" class="field-email__input">,ID 必须与 __input 后缀一致 - 嵌套方式也可行:
<label class="field-email__label">邮箱<input class="field-email__input"></label>,但前提是整个结构包裹在<div class="field-email"> 内 <li>禁止混用:一半用 <code>for,一半嵌套,axe 和 Lighthouse 会直接报「控件无明确关联」
字段级 block 的命名和 DOM 封装是整个验证体系的锚点,一旦松动,后续所有状态控制、无障碍支持、移动端适配都会连锁失效。最易被忽略的是 ID 与 BEM 元素名的严格对应——JS 动态生成表单时,若忘记同步更新
id 值,aria-describedby 就指向了不存在的节点。











