红黄牌制度是协作信号灯而非代码扫描器,红牌仅标记三类可自动化校验的高危可访问性问题(缺失alt/aria-label/label),黄牌提示语义模糊但影响维护的写法,所有状态须绑定具体DOM节点并可追溯。
HTML 本身没有运行时错误,但 aria-label 缺失、alt 空值、嵌套错乱的 section/article 会直接导致可访问性失败、SEO 折损、测试断言飘红。红黄牌不标记“语法错误”,而是标记“协作风险”:比如某人提交了未加 lang 属性的多语言页面,下游翻译组件就会静默失效——这种问题不会报错,但会在 QA 环节或上线后爆发。
人工判罚不可持续。红牌只用于以下三类能被工具稳定捕获的问题:
img 标签缺失 alt 属性,或 alt="" 且非装饰图(需配合 role="presentation" 或 CSS background-image 判定)button、a 等交互元素无文本内容且未提供 aria-label 或 aria-labelledby
input、select、textarea)缺少关联的 label 元素,且未用 aria-label 补充所有规则必须能在 CI 流程中由 axe-core 或 html-validate 输出明确错误 ID(如 aria-input-field-name),不能依赖主观判断。
黄牌不阻断合并,但强制 PR 描述中注明处理方案。典型场景包括:
立即学习“前端免费学习笔记(深入)”;
div + onclick 模拟按钮,而非原生 button —— axe 不报错,但键盘焦点、禁用状态、语义树都缺失h1 到 h6 跳级(如 h2 后直接 h4),影响屏幕阅读器导航逻辑style 写关键布局(如 display: flex),违反样式管控规范黄牌规则需在团队 Wiki 明确列出判定边界,例如“仅当内联样式影响响应式断点或可访问性对比度时才触发”,避免变成风格争论。
不能只说“这个页面有 2 个红牌”,而要定位到:<img src="logo.svg">(第 42 行)、<input type="email">(第 89 行)。CI 报告需生成带行号的 HTML 片段快照,并存档至内部质量看板。开发修复后,必须手动在 PR 中引用对应节点的修复 commit hash,否则黄牌不自动解除。
最容易被忽略的是动态渲染场景:服务端渲染(SSR)和客户端 hydrate 后的 DOM 可能不一致。红牌检查必须在 hydration 完成后执行,否则会漏掉 React 用 dangerouslySetInnerHTML 注入的无效 HTML。