DOCTYPE必须首行全小写且无前置内容,lang属性须用BCP 47规范值如zh-CN,meta charset必须紧接html标签后且为UTF-8,main标签全文档仅限一个且不可嵌套于header等语义容器中。

DOCTYPE必须独占首行且全小写
浏览器看到非标准<!DOCTYPE html>,立刻进怪异模式——document.compatMode变成"BackCompat",Flex布局塌、margin折叠失效、盒模型错乱。这不是警告,是硬性开关。
常见错误包括:<!-- 注释 --><!DOCTYPE html>、PHP动态输出<?php echo '<!DOCTYPE html>'; ?>、大小写混用如<!doctype HTML>、前面多一个空格或BOM字符。这些都会让标准失效。
-
<!DOCTYPE html>必须是文件第一个字符,不能有任何前置内容 - 旧式XHTML声明如
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">已不被HTML5识别,别再用 - 编辑器保存时务必选“UTF-8 without BOM”,VS Code默认可能带BOM,需在设置里关掉
lang属性不是可选项,而是语义刚需
没设lang或设错,屏幕阅读器会把中文读成拼音、拼写检查失灵、Google搜索结果语言标注错位。这不是体验问题,是无障碍合规红线。
根元素<html>必须带lang,且值必须符合BCP 47规范:
立即学习“前端免费学习笔记(深入)”;
- 大陆简体用
lang="zh-CN",台湾繁体用lang="zh-TW" - 禁用
lang="cn"、lang="ch"、lang="zh"这类非标准值 - 局部切换语言可用
<p lang="en">Hello</p>,但不要嵌套滥用,比如<div lang="en"><span lang="zh-CN"></span></div>会导致语音引擎反复切换
meta charset必须紧接之后
<meta charset="UTF-8">位置错了,中文和emoji从第一行就开始乱码,后面再加多少次也救不回来。它决定浏览器解析HTML的初始编码,不是“声明一下就行”的装饰。
正确顺序只能是:
- 第1行:
<!DOCTYPE html> - 第2行:
<html lang="zh-CN"> - 第3行:
<head><meta charset="UTF-8">(必须是<head>内第一个标签)
常见错法:<meta charset="utf8">(缺横杠)、<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">(HTML5中冗余)、<meta charset="utf-8">写在<title>后面——这些都会让编码解析失败。
main标签有不可妥协的语义约束
<main>不是<div class="main">的语义替代品,它是键盘用户按Alt+Shift+M(或辅助技术跳转)直达主要内容区的唯一锚点。违反规则等于主动屏蔽残障用户。
硬性限制非常明确:
- 整个页面只允许出现一次
<main> - 不能嵌套在
<header>、<footer>、<nav>、<aside>内部 - 不能与
<section>混用:主入口文件放<main>,模块片段一律用<section>
拼接多个HTML片段时,最容易漏掉这点——每个片段都带<main>,合并后直接违规。W3C Validator会报Element main not allowed as child of element header或The main element must not appear as a descendant of the header element,别跳过这些报错。



















