Skip to content

DOCTYPE 声明

DOCTYPE 声明是每个 HTML 文档的第一行代码,它告诉浏览器当前页面使用哪种 HTML 版本来解析和渲染。理解 DOCTYPE 的工作原理,是掌握文档结构的基础。

前置知识

阅读本节前,建议先了解:浏览器兼容性与可用性检测

基础概念

什么是 DOCTYPE

DOCTYPE 全称是 Document Type Declaration(文档类型声明)。它位于 HTML 文档的最顶部,在任何 HTML 标签之前,用来告知浏览器该文档所遵循的 HTML 或 XHTML 规范版本。

html
<!DOCTYPE html>

DOCTYPE 不是 HTML 标签,而是一条声明指令。它不属于 HTML 元素,不会出现在 DOM 树中,也不会对页面布局产生任何直接影响。

DOCTYPE 的历史演变

在 HTML 的发展历程中,DOCTYPE 声明经历了从复杂到简化的过程:

HTML 版本DOCTYPE 声明
HTML 2.0<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
HTML 3.2<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
HTML 4.01 Strict<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
HTML 4.01 Transitional<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
XHTML 1.0 Strict<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
XHTML 1.1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
HTML5<!DOCTYPE html>

可以看到,HTML5 将 DOCTYPE 大幅简化为短短一行,这是因为 HTML5 不再基于 SGML(标准通用标记语言),因此不再需要 DTD(文档类型定义)引用。

语法

HTML5 DOCTYPE 语法

html
<!DOCTYPE html>

语法要点:

  • <!DOCTYPE 必须全部大写(虽然 HTML5 不区分大小写,但大写是约定俗成的写法)
  • html 是文档类型标识符,不区分大小写,推荐小写
  • 整条声明前面有 <!,末尾有 >,中间没有斜杠 /
  • 不要在末尾添加自闭合斜杠
html
<!-- 正确 -->
<!DOCTYPE html>

<!-- 也可以(不区分大小写),但不推荐 -->
<!doctype html>
<!DocType Html>

<!-- 不推荐(大小写不统一) -->
<!DOCtype HTML>

<!-- 错误!不要加自闭合斜杠 -->
<!-- <!DOCTYPE html /> -->

<!-- 错误!不要加多余的空格或内容 -->
<!-- <!DOCTYPE html system "about:legacy-compat"> -->

声明位置

DOCTYPE 必须是文档的第一行,前面不能有任何内容,包括空行、空格、注释、BOM(字节顺序标记)等。

html
<!-- 正确:DOCTYPE 是第一行 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>页面标题</title>
</head>
<body>
  <p>页面内容</p>
</body>
</html>
html
<!-- 错误!DOCTYPE 前面有空行 -->
<!-- (空行) -->
<!DOCTYPE html>
<html lang="zh-CN">
...
html
<!-- 错误!DOCTYPE 前面有注释 -->
<!-- 这是我的网站 -->
<!DOCTYPE html>
<html lang="zh-CN">
...

常见陷阱:BOM 问题

如果文件以 UTF-8 BOM(\xEF\xBB\xBF)开头,某些浏览器可能无法正确识别 DOCTYPE。确保编辑器保存文件时使用 UTF-8 without BOM 编码。

详细说明

DOCTYPE 与渲染模式

DOCTYPE 声明的核心作用是决定浏览器的渲染模式。浏览器根据是否存在有效的 DOCTYPE 声明,选择以"标准模式"或"怪异模式"来渲染页面。

标准模式(Standards Mode)

当浏览器检测到有效的 DOCTYPE 声明时,会以标准模式渲染页面。此时浏览器严格按照 W3C/WHATWG 规范来解析和渲染 HTML、CSS。

特点:

  • CSS 布局按标准盒模型计算
  • 元素默认样式遵循规范
  • JavaScript API 行为符合标准

怪异模式(Quirks Mode)

当浏览器没有检测到 DOCTYPE 声明,或者 DOCTYPE 声明无效时,会以怪异模式渲染页面。此时浏览器会模拟旧版本浏览器的行为,以保持与早期网页的向后兼容。

特点:

  • 使用非标准盒模型(IE 盒模型):widthheight 包含 paddingborder
  • 表格元素的默认样式与标准模式不同
  • 某些 CSS 属性行为异常
  • JavaScript 中 document.documentElement.clientWidth 的计算方式不同

近标准模式(Almost Standards Mode)

这是标准模式和怪异模式之间的一个中间模式。大多数行为与标准模式一致,但在表格单元格的垂直对齐方面使用怪异模式的行为。

渲染模式触发条件盒模型表格布局
标准模式有效的 HTML5/XHTML DOCTYPEW3C 标准盒模型严格遵循规范
近标准模式<!DOCTYPE html> 或某些 XHTML transitionalW3C 标准盒模型怪异模式行为
怪异模式无 DOCTYPE 或无效 DOCTYPEIE 盒模型(width 含 padding/border)旧版行为

补充说明

在 HTML5 中,<!DOCTYPE html> 触发的是"近标准模式",而非严格的标准模式。但对于绝大多数开发场景,近标准模式与标准模式的差异可以忽略不计,两者统称为"标准模式"。

各浏览器渲染模式对照

html
<!-- 标准模式 / 近标准模式 -->
<!DOCTYPE html>
<!DOCTYPE HTML>
<!doctype html>

<!-- 怪异模式 -->
(无 DOCTYPE 声明)
<html>

怪异模式下的具体差异

了解怪异模式与标准模式的具体差异,有助于理解 DOCTYPE 的重要性:

1. 盒模型差异

css
/* 标准模式下 */
.box {
  width: 200px;
  padding: 20px;
  border: 1px solid #000;
  /* 实际占用宽度 = 200 + 20*2 + 1*2 = 242px */
}

/* 怪异模式下(同一 CSS) */
.box {
  width: 200px;
  padding: 20px;
  border: 1px solid #000;
  /* 实际占用宽度 = 200px(padding 和 border 包含在 width 内) */
  /* 内容区域 = 200 - 20*2 - 1*2 = 158px */
}

2. 图片默认行为

html
<!-- 标准模式:img 是行内元素,底部可能有 3~5px 间距 -->
<img src="photo.jpg" alt="照片">

<!-- 怪异模式:img 的基线对齐行为不同 -->

3. 百分比高度计算

css
/* 标准模式:height: 100% 需要父元素有明确的高度 */
/* 怪异模式:height: 100% 可以相对于视口计算 */

HTML5 DOCTYPE 与 HTML4/XHTML 的区别

特性HTML4/XHTMLHTML5
声明长度很长(包含 FPI 和 DTD URL)极短(仅 <!DOCTYPE html>
是否基于 SGML
DTD 引用必须引用外部 DTD 文件不需要
大小写推荐大写 DOCTYPE不区分大小写
严格程度有 Strict / Transitional / Frameset 之分统一一种
是否必须技术上可选(但强烈推荐)强烈推荐,不加则触发怪异模式

实战示例

最小化的完整 HTML5 文档

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DOCTYPE 演示</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      max-width: 800px;
      margin: 40px auto;
      padding: 0 20px;
      line-height: 1.6;
    }
    .demo-box {
      width: 200px;
      padding: 20px;
      border: 5px solid #333;
      background-color: #f0f0f0;
      margin: 20px 0;
    }
    .info {
      background-color: #e8f4fd;
      padding: 15px;
      border-radius: 4px;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <h1>DOCTYPE 声明演示</h1>
  <p>当前页面使用 <code>&lt;!DOCTYPE html&gt;</code> 声明,以标准模式渲染。</p>

  <h2>盒模型演示</h2>
  <div class="demo-box">
    宽度: 200px<br>
    内边距: 20px<br>
    边框: 5px<br>
    实际占用宽度: 250px
  </div>
  <div class="info">
    <p>在标准模式下,此盒子的实际占用宽度为 200 + 20×2 + 5×2 = <strong>250px</strong>。</p>
    <p>如果在怪异模式下,实际占用宽度将只有 <strong>200px</strong>,内容区域会被压缩。</p>
  </div>
</body>
</html>

对比实验:有无 DOCTYPE 的差异

html
<!-- 文件 A:有 DOCTYPE(标准模式) -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>标准模式</title>
  <style>
    .box {
      width: 200px;
      padding: 20px;
      border: 5px solid #333;
      background-color: #d4edda;
    }
  </style>
</head>
<body>
  <div class="box">标准模式盒子</div>
  <script>
    // 输出实际渲染宽度
    var box = document.querySelector('.box');
    console.log('offsetWidth:', box.offsetWidth);
    // 标准模式输出: 250
  </script>
</body>
</html>
html
<!-- 文件 B:无 DOCTYPE(怪异模式) -->
<!-- 注意:这里故意省略 DOCTYPE 以演示怪异模式 -->
<html>
<head>
  <meta charset="UTF-8">
  <title>怪异模式</title>
  <style>
    .box {
      width: 200px;
      padding: 20px;
      border: 5px solid #333;
      background-color: #f8d7da;
    }
  </style>
</head>
<body>
  <div class="box">怪异模式盒子</div>
  <script>
    // 输出实际渲染宽度
    var box = document.querySelector('.box');
    console.log('offsetWidth:', box.offsetWidth);
    // 怪异模式输出: 200
  </script>
</body>
</html>

使用 JavaScript 检测渲染模式

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>渲染模式检测</title>
</head>
<body>
  <h1>当前页面渲染模式</h1>
  <p id="mode-info">检测中...</p>

  <script>
    // 检测渲染模式的方法
    function getRenderingMode() {
      if (document.compatMode === 'CSS1Compat') {
        return '标准模式(Standards Mode / Almost Standards Mode)';
      } else if (document.compatMode === 'BackCompat') {
        return '怪异模式(Quirks Mode)';
      }
      return '未知模式';
    }

    document.getElementById('mode-info').textContent =
      'document.compatMode = "' + document.compatMode + '"' +
      '\n渲染模式:' + getRenderingMode();
  </script>
</body>
</html>

注意事项

常见错误

1. 忘记写 DOCTYPE

html
<!-- 错误!没有 DOCTYPE 声明 -->
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>我的页面</title>
</head>
<body>
  <!-- 将以怪异模式渲染 -->
</body>
</html>

这是新手最常犯的错误。没有 DOCTYPE 的页面会进入怪异模式,导致 CSS 布局与预期不符。

2. DOCTYPE 前面有空行或空格

html
<!-- 错误!DOCTYPE 前面有内容 -->

<!DOCTYPE html>
<html lang="zh-CN">
...

某些浏览器可能会因此进入怪异模式。

3. 拼写错误

html
<!-- 错误!拼写错误 -->
<!DOCTPYE html>
<!DOCTYE html>
<!DOCTYP html>

4. 使用过时的 HTML4 DOCTYPE

html
<!-- 不推荐!虽然能触发标准模式,但没必要使用旧语法 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

DOCTYPE 不会影响的内容

  • 页面的功能不受影响
  • JavaScript 的功能不受影响
  • HTML 标签的使用不受影响
  • 影响浏览器的渲染模式

与 XHTML 的关系

XHTML 1.0 和 XHTML 1.1 有自己的 DOCTYPE 声明。如果你维护的是旧版 XHTML 页面,可能还会看到这些声明。但在新项目中,统一使用 HTML5 的 <!DOCTYPE html> 即可。

迁移提示

如果你正在将旧的 HTML4 或 XHTML 页面迁移到 HTML5,只需将 DOCTYPE 替换为 <!DOCTYPE html> 即可。这是迁移的第一步,也是最简单的一步。

最佳实践

1. 每个页面都必须有 DOCTYPE

无论页面多简单,都不要省略 DOCTYPE 声明:

html
<!-- 即使是最简单的页面也要有 DOCTYPE -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>简单页面</title>
</head>
<body>
  <p>Hello, World!</p>
</body>
</html>

2. 使用 HTML5 简化声明

不再使用 HTML4 或 XHTML 的长串 DOCTYPE:

html
<!-- 推荐 -->
<!DOCTYPE html>

<!-- 不推荐 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

3. 使用代码编辑器模板

在 VS Code 等编辑器中,输入 ! 然后按 Tab 键,Emmet 会自动生成包含 DOCTYPE 的 HTML5 模板:

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
</html>

4. 项目模板统一

在项目中创建统一的 HTML 模板文件,确保所有页面都以正确的 DOCTYPE 开头。可以配合构建工具(如 Vite、Webpack 的 HTML 插件)自动注入。

5. 代码审查时检查 DOCTYPE

将"检查 DOCTYPE 声明"纳入代码审查清单,确保团队成员不会遗漏。

DOCTYPE 速查表

项目说明
声明语法<!DOCTYPE html>
位置文档第一行,前面不能有任何内容
大小写推荐大写 DOCTYPE,小写 html
作用触发浏览器标准模式渲染
省略后果浏览器进入怪异模式,布局可能异常
是否为 HTML 标签不是,它是一条声明指令
HTML5 特有是,HTML5 简化了 DOCTYPE

下一节

继续学习:html 根元素

参考链接