doctype和lang属性必须写在首行且不可省略:须为第一行无空格或注释,lang必须用精确值如zh-cn而非zh,否则触发怪异模式或无障碍失效。

DOCTYPE 和 lang 属性必须写在首行且不可省略
不加 !DOCTYPE html 或漏掉 lang,浏览器可能进入怪异模式,导致 CSS 重置失效、Flex/Grid 行为异常,甚至 JS 获取的 document.body 高度不准。这不是“看起来差不多”的问题,而是底层解析逻辑切换。
-
!DOCTYPE html必须是文件第一行,前后不能有空格或注释 -
中的zh-CN不可简写为zh,否则部分屏幕阅读器无法加载对应语音库 - 若页面含多语言内容(如中英双语),主语言仍用
lang="zh-CN",局部切换单个元素时再用lang="en-US"
语义标签不是“换 div 就完事”,而是结构约束
把 <div class="header"> 改成 <code><header></header> 只是起点;真正容易出错的是后续嵌套规则——比如 <main></main> 里塞了 <header></header> 没问题,但塞 <nav></nav> 就得确认它是否属于主内容导航;<section></section> 没配 <h2></h2> 到 <h6></h6> 会被 W3C 验证器标为“结构无效”。
-
<main></main>全局唯一,且不能出现在<article></article>、<aside></aside>或<nav></nav>内部 -
<article></article>必须能独立分发(如 RSS 抓取),<section></section>只是逻辑分组,二者语义不可互换 -
<time datetime="2026-07-01">今天</time>的datetime值必须是机器可解析格式,不能写成"今天"或"7月1日"
alt 属性和 label 关联不是“填个空就过关”
alt="" 和 alt="图标" 效果完全不同:前者明确告知辅助技术“这是纯装饰”,后者会把“图标”二字读出来,干扰用户理解。同理,<input id="email"> 单独存在毫无意义,必须配 <label for="email">邮箱地址</label>,否则 VoiceOver 等工具无法将文字与控件绑定。
- 功能性图片(如按钮图标、图表)的
alt必须描述行为或含义,例如alt="搜索按钮",而非alt="magnifier.png" -
<label></label>和<input>的id/for必须严格一致,大小写敏感,且不能重复 - 隐藏文本(如仅用于屏幕阅读器的说明)要用
class="sr-only"+ CSSclip: rect(1px, 1px, 1px, 1px),不能靠display: none或visibility: hidden
HTML 验证不是上线前走流程,而是开发中实时拦截
W3C Validator 能发现 <img> 缺 alt、<form></form> 没 method、<button></button> 缺 type 这类低级但致命的问题,但等手动提交才查就晚了。真正有效的做法是把它集成进编辑器和 CI 流程。
- VS Code 安装
HTMLHint插件后,在.htmlhintrc中启用"attr-req-alt"、"tag-pair"、"id-unique"等规则 - CI 阶段用
html-validateCLI 扫描所有.html文件,失败则阻断构建 - 注意:验证器不检查语义合理性(比如误用
<section></section>包裹单个段落),这部分需靠人工 Review 或 axe-core 辅助
<main></main> 的唯一性校验和 lang 的区域码精度——它们不出视觉错误,但会让自动化测试、SEO 抓取、无障碍审计接连失败。











