必须将<!DOCTYPE html>置于HTML文件第一行且前面不能有任何字符,否则IE6–IE9等浏览器会立即进入Quirks模式;推荐唯一无歧义写法是<!DOCTYPE html>,避免旧DTD、大小写混用或缺失URI等触发非标准模式。

DOCTYPE 必须独占第一行,前面不能有任何字符
浏览器(尤其是 IE6–IE9)只要在 <!DOCTYPE html> 前看到任意一个字符——哪怕是一个空格、<!-- comment -->、UTF-8 BOM 或 <?xml version="1.0"?>——就会立刻降级到 Quirks 模式。
常见出问题的场景:
- PHP/JSP 模板里
<?php echo $debug_info; ?>插在 DOCTYPE 前 - 用 Windows 记事本保存的 .html 文件自带 UTF-8 BOM
- Webpack/Vite 构建时自动注入 runtime 脚本或注释,被插到 HTML 开头
- Vue/React SSR 渲染时,服务端模板拼接逻辑多输出了一个换行或空格
验证方法:用浏览器开发者工具执行 document.doctype,返回 null 就说明没生效;再查 document.compatMode,值为 "BackCompat" 就是 Quirks 模式。
只用 <!DOCTYPE html>,别写旧版 DTD
<!DOCTYPE html> 是唯一推荐、无歧义、全浏览器兼容的标准写法。其他看似“标准”的声明,实际可能触发 Almost Standards Mode 或 Quirks Mode。
立即学习“前端免费学习笔记(深入)”;
这些写法要避开:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">(缺 URI,IE 直接 Quirks) -
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">(XHTML 声明,在现代浏览器中不必要,且 Safari 某些版本会进 Almost Standards Mode) -
<!doctype html>(小写 doctype,IE8 及更早内核识别失败)
注意:<!DOCTYPE HTML> 大写但没小写 html,部分 Safari 版本也会退化为 Almost Standards Mode,影响 <table> 内图片的 vertical-align 行为。
Quirks Mode 下最易翻车的 CSS 行为
盒模型差异只是表象,真正让开发踩坑的是那些“看起来正常、切模式就崩”的细节:
-
width: 200px; padding: 10px; border: 2px:Quirks 模式下总宽仍是 200px;Standards 模式下是 224px —— 复用老 CSS 时布局会突然错位 -
height: 100%:Quirks 模式下常“自动撑开”,Standards 模式必须父元素有明确高度(如height: 100vh),否则无效 -
margin: auto水平居中块级元素:Quirks 模式下可能意外生效,Standards 模式要求display: block+ 明确宽度 - 表格单元格内图片默认基线对齐方式不同,导致行高异常(Almost Standards Mode 也有此问题)
这类问题往往上线后才暴露,尤其当页面从旧系统迁移、或接入新构建流程时。
别信“页面看起来没问题”,必须主动验证模式
很多页面在 Chrome 里显示正常,不代表没进 Quirks 模式——因为 Chrome 对 Quirks 的兼容处理比 IE/Edge 宽松得多。但一旦用户用旧 Edge 或企业内网 IE,或者未来 Chrome 更新渲染引擎,问题就会浮现。
验证不能只看源码有没有写 <!DOCTYPE html>,得看它是否真被浏览器识别:
- 打开控制台,运行
document.compatMode,必须是"CSS1Compat" - 检查
document.doctype是否存在且name === "html" - Lighthouse 报告里 “Page lacks a valid <!DOCTYPE>” 警告要当真,不是可忽略项
最容易被忽略的是:构建产物 HTML 文件开头肉眼看着干净,但实际被插入了不可见字符(比如 BOM 或零宽空格),这种问题只能靠脚本校验或 hex 查看器确认。


















