html代码质量必须在提交阶段卡住,否则会埋下渲染错位、seo失效、无障碍访问失败等隐患;html-validate支持pre-commit和ci双卡位,可锁定title非空、img必含alt、禁止div包裹h1-h6三条底线。

HTML 代码质量不能靠上线后靠肉眼检查,必须在提交阶段就卡住。否则每次 git push 都可能埋下渲染错位、SEO 失效、无障碍访问失败的隐患,而这些在 CI 流水线里根本不会报错。
为什么 HTML Lint 工具常被跳过?
很多团队把 eslint 或 phpstan 加进 CI 就算“有质量门禁”,但 HTML 往往被当成“静态资源”放行——其实它才是用户最先感知到的层。常见误区包括:
- 误以为构建工具(如 Webpack/Vite)会自动校验语义结构,实际只处理打包,不校验
<main></main>是否缺失、<img>是否漏alt - 用浏览器开发者工具人工检查,但无法覆盖所有页面路径、响应式断点、屏幕阅读器行为
- 把 HTML 校验塞进“测试阶段”,结果因缺少 DOM 环境导致
jest+@testing-library只能测逻辑,不查标签嵌套合法性
用 html-validate 在 pre-commit 和 CI 双卡位
html-validate 是目前对初创团队最友好的 HTML Linter:配置轻、规则可裁剪、支持自定义规则、输出格式兼容 Git 工具链。关键不是全开规则,而是锁定三条底线:
- 必含
<title></title>且非空(防 SEO 归零) - 所有
<img>必须有alt属性(防无障碍失效) - 禁止
<div> 包裹 <code><h1></h1>到<h6></h6>的非法嵌套(防语义结构崩坏)在
.htmlvalidate.json中显式声明:{ "rules": { "valid-title": "error", "require-alt": "error", "no-redundant-role": "warn", "heading-order": "error" } }再通过
husky绑定pre-commit钩子,确保本地提交前就拦截;CI 阶段(如.gitlab-ci.yml)加一行:html-validate src/**/*.html,失败即中断流水线。绕过模板引擎导致的假阳性问题
Vue/React 模板或 PHP 混排 HTML 时,
html-validate常报“未闭合标签”或“属性未加引号”——这不是 bug,是解析器没理解模板语法。解决方式只有两个:- 用
html-validate的parser插件适配:Vue 项目装@html-validate/vue-parser,并在配置中指定"parser": "@html-validate/vue-parser" - 对 PHP 模板,改用
php -l预检 + 提取纯 HTML 片段再喂给html-validate,避免直接校验含<?php ?>的文件
切忌用
/* html-validate-disable */全局关闭——那等于把质量红线涂掉。和自动化截图比对联动,暴露视觉层缺陷
仅校验 HTML 结构还不够。比如
display: none错写成display: non,html-validate不管,但用户看到的是白屏。此时需在 CI 中加一步视觉回归:- 用
playwright启动无头浏览器,访问关键路由(如/login、/product/123) - 截取首屏快照,与基准图做像素比对(推荐
pixelmatch) - 差异超过阈值(如 0.5%)则失败,并附对比图链接供快速定位
这步不替代 HTML 校验,但补上了“结构合法 ≠ 渲染正常”的最后一环。初创团队初期可先跑 3–5 个核心页面,别一上来扫全站。
真正难的不是加工具,而是让每个成员理解:HTML 不是“写完就能跑”的中间产物,它是交付物的第一行契约。少一个
alt,就可能让视障用户卡在登录页;多一层无意义<div>,就可能让搜索引擎降权。这些都不是“上线后再修”的问题。</div> - 用











