HTML文档结构是浏览器解析渲染的强制契约:必须首行唯一声明<!DOCTYPE html>,<html>须带lang属性(如lang="zh-CN"),<meta charset="UTF-8">须紧接<head>开头且早于<title>,缺一将致怪异模式、乱码、DOM不可用或SEO失效。

HTML文档结构不是“可选写法”,而是浏览器解析和渲染页面的强制契约。漏掉<!DOCTYPE html>或把<head>和<body>写错层级,轻则样式错乱,重则脚本不执行、SEO失效。
为什么<!DOCTYPE html>必须放在第一行
它不是HTML标签,而是告诉浏览器:“用标准模式解析,别退回怪异模式(Quirks Mode)”。一旦前面有空格、BOM字符或注释,浏览器就可能降级为怪异模式——这时box-sizing、vertical-align等行为全都不一样,连document.body都可能为null。
- ✅ 正确:文件开头第一字符就是
<!DOCTYPE html> - ❌ 错误:
<!-- 注释 --><!DOCTYPE html>或\ufeff<!DOCTYPE html>(UTF-8 BOM) - ⚠️ 注意:Node.js生成HTML时,
fs.writeFileSync()默认不带BOM,但某些编辑器保存会悄悄加BOM
<html>的lang属性到底要不要设
不设lang不是语法错误,但会影响屏幕阅读器发音、搜索引擎语义判断,甚至CSS里的:lang()伪类无法匹配。中文页面必须写<html lang="zh-CN">,不能简写成zh或留空。
- ✅ 推荐:
<html lang="zh-CN">(中国大陆)、zh-TW(台湾)、en-US - ❌ 常见错误:
<html lang="cn">(无效值)、<html lang="">(等同于未声明) - ⚠️ 影响:Chrome DevTools 的“Accessibility”面板会标红提示缺失
lang
<meta charset="UTF-8">为什么必须在<title>之前
浏览器从上到下解析HTML,遇到第一个<meta charset>才确定编码方式。如果它在<title>之后,<title>里的中文就会被当成乱码解码一次,再被修正——此时页面标题栏已显示乱码,刷新也救不回来。
立即学习“前端免费学习笔记(深入)”;
- ✅ 位置:必须是
<head>内**最早**的标签之一,紧接<title>前或后均可,但绝不能晚于<title> - ❌ 错误顺序:
<title>测试页</title><meta charset="UTF-8"> - ⚠️ 补充:
<meta>的charset属性只能用于<head>,且一个文档只允许出现一次
<head>里能放<script>吗?放了会怎样
可以放,但行为和放在<body>底部完全不同:它会阻塞HTML解析,直到脚本下载并执行完。如果脚本里调用document.write()或直接操作document.body,大概率报错——因为<body>还没开始解析。
- ✅ 安全做法:
<script src="init.js" defer>(延迟执行)或<script src="init.js" type="module">(自动defer) - ❌ 高危写法:
<script>console.log(document.body)</script>(此时document.body === null) - ⚠️ 性能影响:未加
defer或async的<script>在<head>中,会使首屏时间(FCP)明显变长
真正容易被忽略的,是<meta name="viewport">在移动端的必要性——没有它,iOS Safari会以980px宽度渲染,文字小得看不清,缩放交互也异常。这和结构看似无关,却是现代HTML文档实际生效的隐性门槛。



















