必须顶格写在第一行,是浏览器进入标准模式的唯一钥匙;若前面有空格、注释或bom,将触发怪异模式,导致box-sizing失效、flex错乱、sticky不工作等严重渲染问题。

HTML 不是某个公司或组织私有的“行业标准”,而是由 W3C(万维网联盟)和 WHATWG(网页超文本应用技术工作小组)共同维护的开放技术规范。 它没有强制法律效力,但浏览器厂商必须实现其核心部分,否则网页就无法正常渲染——换句话说,DOCTYPE、lang、charset 这些不是“建议”,而是浏览器解析页面的启动开关,漏一个,后续所有行为都可能偏移。
为什么 必须顶格写在第一行
它不是装饰,是浏览器进入“标准模式”的唯一钥匙。一旦前面有空格、注释、BOM 字节或换行,IE 和旧 Safari 就会退化到怪异模式(Quirks Mode),后果包括:box-sizing 失效、flex 布局错乱、position: sticky 彻底不工作。W3C Validator 会直接报 fatal error,CI/CD 流水线常因此阻断发布。
- ✅ 正确写法:
(全小写,无空格,无注释,无 BOM) - ❌ 错误写法:
<!-- comment -->、<code>、<code>(零宽空格藏在开头) - ⚠️ 注意:某些编辑器(如 VS Code 在 UTF-8-BOM 模式下保存)会悄悄加 BOM,导致第一行看似空白实则不可见
不只是给翻译用的
这个属性决定三件事:屏幕阅读器发音语种、搜索引擎识别页面语言、Chrome 地址栏翻译按钮是否出现。写成 lang="cn" 或 lang="",翻译功能直接失效;写成 lang="en" 却放中文内容,Google 可能降权。
- 中文站点固定用
zh-CN(简体)、zh-TW(繁体),不能简写为zh - 多语言站点需动态更新:
document.documentElement.lang = "ja",不能只靠初始静态值 - 服务端渲染时,务必确保模板中
lang值与实际语言一致,否则 SSR 和 CSR 语言不一致会触发 hydration mismatch
<meta charset="UTF-8"> 必须放在 最前面
它告诉浏览器:“从第 1 个字节开始就用 UTF-8 解码”。如果它不在 开头,前面的标签(比如 <title></title>)可能已被按 ASCII 或系统默认编码解析过,导致标题乱码——而且这种乱码无法通过后续 JS 修复。
- ✅ 正确顺序:
<meta charset="UTF-8">→<title></title>→ 其他<meta> - ❌ 常见错误:把
<meta charset>放在<title></title>后面,或嵌套在<script></script>里 - ⚠️ 注意:某些 CMS 或模板引擎会自动注入
<meta>,需检查最终输出 HTML 的真实顺序
块级标签闭合不是“可选”,是 DOM 树稳定的前提
省略
看似省事,但浏览器自动补全的逻辑和你预期往往不一致。JS 操作 element.children 时拿到的节点顺序、长度可能和源码对不上;服务端模板(如 Django、Nunjucks)遇到未闭合标签,可能整段输出错位,调试成本翻倍。- ✅ 所有块级标签(
<div>、<code><p></p>、<section></section>、<header></header>等)显式闭合 - ✅ 自闭合标签统一用
<img src="x" alt="">形式(无尾部斜杠) - ⚠️ 特别注意嵌套场景:
<div><p>text</p></div> <p>more</p>会被修正为<div><p>text</p></div> <p>more</p>,但 JS 里div.children只有 1 个p节点,而非你写的 2 个
真正难的不是记住每条规则,而是在写第一个 标签、第一个 class、第一张 <img> 时,不假思索就做对那几件关键小事——因为浏览器不会提醒你“这里错了”,它只会默默按自己的理解去猜,然后把问题留给 QA、用户、或三个月后的你自己。











