doctype、lang、charset 必须写在最前面,否则浏览器几乎必然进入怪异模式,导致 flex/grid 失效、盒模型错乱、seo 元素不被识别;html 结构需严格遵循语义规范,dom 实际结构才是渲染依据。

DOCTYPE、lang、charset 必须写在最前面
没这三样,浏览器大概率进怪异模式(Quirks Mode),Flex/Grid 失效、盒模型错乱、SEO 元素不被识别——不是“可能”,是几乎必然发生。
必须是文件第一行,前面不能有任何字符(包括 BOM、空格、注释)-
要紧跟其后,lang值必须匹配实际语言,zh不够,zh-Hans或zh-CN才有效;JS 里读document.documentElement.lang只在页面加载时生效,改了也不刷新语义 -
<meta charset="UTF-8">必须出现在最靠前位置(建议前 1024 字节内),晚于它写的<title></title>或<link>可能导致 emoji 显示为 ,Safari 甚至会忽略后续<meta>
head 里只放元数据,别塞可见内容
把 <h1></h1>、<p></p>、<div> 放进 <code>,W3C 验证器报 Stray end head tag 是表象,真正问题是浏览器已隐式关闭 并开始解析 ——你写的显式 标签反而成了“重复开启”。
-
<title></title>、<meta>、<link>、<style></style>、<script></script>(无defer/async时建议挪到底部)可以放 -
<script></script>放顶部且没加defer,可能触发 DOM 未就绪错误,比如document.getElementById is not a function - 常见误操作:
<link rel="stylesheet">后面跟了个<h2>标题</h2>——这个<h2></h2>实际已被浏览器塞进,但你源码里看不见它在哪
body 内容必须嵌套在语义化容器中,不能裸奔
直接写 <p>正文</p> 没错,但整页只有 <div> 套 <code><div>,可访问性工具(NVDA/VoiceOver)会当它是“无结构文本”,搜索引擎也难提取主次关系。
<ul>
<li>
<code><main></main> 只能出现一次,且不能被 <section></section>、<article></article> 等包裹(否则失效)
<header></header> 和 <footer></footer> 可以多处使用,但 <nav></nav> 应只用于主导航(不是每个菜单都叫 <nav></nav>)<ul></ul>/<ol></ol> 必须直接子元素是 <li>,中间插 <div> 或 <code><p></p> 会导致屏幕阅读器跳过部分条目
<figure>+<figcaption></figcaption></figure> 包裹图文组合,比单纯 <div>
<img><p>说明</p>
</div> 更利于语义解析DOM 结构比源码缩进更可信,必须用 Elements 面板验证
你写的 HTML 源码可能是错的,但浏览器解析后的 DOM 才是真实渲染依据。缩进整齐 ≠ 结构正确,尤其当标签漏闭合或嵌套非法时,浏览器会自动“修复”,结果常和你预期相反。
- Elements 面板里灰色斜体标签 = 被浏览器补全或截断的证据(比如漏闭合的
<div> 末尾显示为 <code><div> 斜体) <li>右键父节点 → “Edit as HTML”,删一个字符再回车:如果子树重排,说明原始 HTML 已被修正过</li> <li>执行 <code>document.body.innerHTML,对比本地源码——多出来的、消失的<section></section>就是问题线索 - 别信 Auto Close Tag 插件补的标签,它不管对不对,只管配对;
<p></p> <div>xxx</div>它照样帮你闭合,但这是 HTML5 明确禁止的嵌套
复杂点在于:浏览器的容错机制掩盖了错误,而开发者常依赖“看起来正常”来判断代码是否正确。真正要盯住的,是 DOM 实际结构、W3C 验证结果、以及屏幕阅读器的实际播报顺序。











