Skip to content

HTML 规范文档

HTML 规范文档是 Web 开发者最权威的参考来源。了解如何阅读和利用 WHATWG HTML 规范文档,能够帮助你准确理解 HTML 元素和 API 的定义、行为规则以及边界条件。本节将教你如何高效阅读规范文档。

前置知识

阅读本节前,建议先了解:W3C 与 WHATWG

基础概念

WHATWG HTML Living Standard 是当前唯一的 HTML 权威规范,它以活标准(Living Standard)的形式持续维护更新。规范文档详细定义了每个 HTML 元素的语法、语义、属性、行为规则,以及浏览器应该如何解析和渲染这些元素。

规范文档地址

text
主要规范文档:

1. HTML Living Standard(主规范)
   → https://html.spec.whatwg.org/
   → 包含所有 HTML 元素、属性、DOM API 的定义

2. WHATWG 规范列表
   → https://spec.whatwg.org/
   → 包含 Fetch、Streams、URL 等相关规范

3. W3C CSS 规范
   → https://www.w3.org/Style/CSS/
   → CSS 各级别的规范文档

4. MDN Web Docs(开发者友好的文档)
   → https://developer.mozilla.org/zh-CN/docs/Web/HTML
   → 基于 W3C/WHATWG 规范编写的实用开发者文档

规范文档结构

HTML Living Standard 的整体结构

WHATWG HTML Living Standard 是一个超长文档(数万行),但结构清晰,分为若干大章节:

text
HTML Living Standard 章节结构(简化版):

1. Introduction(引言)
   → 规范的范围、约定、术语定义

2. Common infrastructure(通用基础设施)
   → 术语表、资源类型、安全模型

3. Semantics(语义)
   → HTML 文档的语义结构
   → 所有 HTML 元素的详细定义
   → 这是开发者最常查阅的章节

4. The elements of HTML(HTML 元素)
   → 按类别分组的所有 HTML 元素
   → 每个元素的完整定义

5. Microdata(微数据)
   → 嵌入式结构化数据

6. Loading resources(加载资源)
   → 浏览器如何加载和处理外部资源

7. Cross-origin policies(跨域策略)
   → CORS 等安全机制

8. Fetching resources(获取资源)
   → 网络请求的处理流程

9. Parsing HTML documents(HTML 解析)
   → HTML 解析器的算法和行为

10. Rendering(渲染)
    → 浏览器如何将 HTML 渲染为视觉输出

11. Scripting(脚本)
    → JavaScript 在 HTML 中的执行规则

12. Web application APIs(Web 应用 API)
    → 与 HTML 相关的 Web API 定义

查找特定元素

规范文档的 "The elements of HTML" 章节按类别组织元素:

text
HTML 元素分类:

1. Main(主内容)
   → <body>, <article>, <section>, <nav>, <aside>, <h1>~<h6>,
     <header>, <footer>, <address>, <hgroup>

2. Text-level(文本级语义)
   → <a>, <em>, <strong>, <small>, <s>, <cite>, <q>, <dfn>,
     <abbr>, <ruby>, <data>, <time>, <code>, <var>, <samp>,
     <kbd>, <sub>, <sup>, <i>, <b>, <u>, <mark>, <bdi>,
     <bdo>, <span>, <br>, <wbr>

3. Edits(编辑相关)
   → <ins>, <del>

4. Embedded(嵌入内容)
   → <img>, <iframe>, <embed>, <object>, <picture>,
     <source>, <map>, <svg>, <math>

5. Tabular data(表格数据)
   → <table>, <caption>, <colgroup>, <col>, <tbody>,
     <thead>, <tfoot>, <tr>, <td>, <th>

6. Forms(表单)
   → <form>, <label>, <input>, <button>, <select>,
     <datalist>, <optgroup>, <option>, <textarea>,
     <output>, <progress>, <meter>, <fieldset>,
     <legend>

7. Interactive(交互)
   → <details>, <summary>, <dialog>

8. Scripting(脚本)
   → <script>, <noscript>, <template>, <slot>

详细说明

规范文档的元素定义格式

每个 HTML 元素在规范中的定义遵循固定的格式。以 <section> 元素为例:

text
4.4.2 The section element
Categories:
  Flow content.
  Sectioning content.
  Palpable content.
Contexts in which this element can be used:
  Where flow content is expected.
Content model:
  Flow content.
Tag omission in text/html:
  Neither tag is omissible.
Content attributes:
  Global attributes.
Accessibility considerations:
  For authors. For implementers. {对应文档链接}
Usage summary:
  The section element represents a generic section of a
  document or application. A section, in this context,
  is a thematic grouping of content, typically with a heading.

  Examples of sections would be chapters, tabbed pages,
  or numbered sections of a thesis. A Web site's home page
  could be split into sections for an introduction, news
  items, and contact information.

  ...

关键术语解释

在阅读规范之前,需要理解以下核心术语:

text
核心术语:

1. Content categories(内容类别)
   - Flow content(流内容):大部分元素都属于此类
   - Sectioning content(分区内容):创建内容区域的元素
   - Heading content(标题内容):h1-h6、hgroup
   - Phrasing content(短语内容):文本和行内元素
   - Embedded content(嵌入内容):img、video、iframe 等
   - Interactive content(交互内容):a、button、input 等
   - Palpable content(可感知内容):有实际渲染输出的内容

2. Content model(内容模型)
   - 描述一个元素可以包含哪些类型的内容
   - 如:<p> 的内容模型是 Phrasing content

3. Tag omission(标签省略)
   - 某些元素的开始或结束标签可以省略
   - 如:<html>、<head>、<body> 的结束标签可以省略
   - 如:<li> 的结束标签在特定条件下可省略

4. Global attributes(全局属性)
   - 所有 HTML 元素都可使用的属性
   - 包括 id、class、style、title、lang、hidden、
     contenteditable、tabindex、draggable 等

5. ARIA roles(ARIA 角色)
   - 无障碍相关的角色映射
   - 规范中会说明每个元素默认的隐式 ARIA 语义

内容类别详解

内容类别是规范中最基础的概念之一,它定义了元素之间的关系:

html
<!-- 示例:内容类别的实际含义 -->

<!-- p 元素的内容模型是 "Phrasing content" -->
<p>
  这是短语内容,可以包含文本和行内元素:
  <strong>粗体</strong>、<em>斜体</em>、<a href="#">链接</a>
</p>

<!-- p 元素不能包含 "Flow content"(块级元素) -->
<!-- 错误示例:p 内部嵌套 div -->
<p>
  <div>这会导致浏览器自动关闭 p 标签</div>
</p>

<!-- section 的内容模型是 "Flow content" -->
<section>
  <h2>标题</h2>
  <p>段落</p>
  <div>块级元素</div>
</section>
text
内容类别层级关系:

文档根元素
└── 元数据内容(meta, link, style, title, base, script, noscript, template)
└── 流内容(几乎所有可见元素)
    ├── 分区内容(section, article, aside, nav)
    ├── 标题内容(h1~h6, hgroup)
    ├── 短语内容(文本, a, span, strong, em, code, img 等)
    ├── 嵌入内容(img, video, audio, canvas, iframe, svg, math)
    └── 交互内容(a[href], button, input, select, textarea, details)

如何快速定位规范内容

text
查找策略:

1. 使用浏览器搜索(Ctrl+F)
   → 规范文档是单一 HTML 页面
   → 在页面内搜索元素名称如 "The a element"

2. 使用规范目录(Table of Contents)
   → 文档顶部有完整的章节目录
   → 点击即可跳转到对应位置

3. 使用 MDN 中的规范引用
   → MDN 每个元素页面底部有 "Specifications" 部分
   → 直接链接到规范中对应的定义位置

4. 使用 WHATWG 的 issue tracker
   → https://github.com/whatwg/html/issues
   → 搜索元素名称查看相关讨论

5. 使用浏览器开发者工具
   → Elements 面板中选中元素
   → Console 中输入 $$('element')[0].constructor 查看对应接口

实战示例

示例:在规范中查找 <details> 元素的定义

text
操作步骤:

1. 打开 https://html.spec.whatwg.org/
2. 按 Ctrl+F,搜索 "The details element"
3. 阅读该元素的定义:

   Categories:
     Flow content.
     Sectioning root.
     Interactive content.
     Palpable content.

   Content model:
     One <summary> element followed by flow content.

   Accessibility considerations:
     For authors. For implementers.

   这告诉我们:
   - details 是流内容、分区根、交互内容、可感知内容
   - 它的内容模型:一个 summary 元素 + 任意流内容
   - 有无障碍方面的考虑

示例:使用规范验证元素嵌套规则

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>规范验证:元素嵌套规则</title>
  <style>
    :root {
      --primary: #2563eb;
      --bg: #f8fafc;
      --text: #1e293b;
      --muted: #64748b;
      --border: #e2e8f0;
      --success: #16a34a;
      --danger: #dc2626;
      --radius: 8px;
    }

    * { margin: 0; padding: 0; box-sizing: border-box; }

    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
      background: var(--bg);
      color: var(--text);
      line-height: 1.6;
      padding: 2rem;
    }

    .container { max-width: 700px; margin: 0 auto; }
    h1 { color: var(--primary); margin-bottom: 1rem; }

    .example {
      background: white;
      border-radius: var(--radius);
      padding: 1.5rem;
      margin-bottom: 1rem;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    }

    .example h3 { margin-bottom: 0.75rem; }

    .valid { border-left: 4px solid var(--success); }
    .invalid { border-left: 4px solid var(--danger); }

    .label {
      display: inline-block;
      padding: 0.15rem 0.5rem;
      border-radius: 4px;
      font-size: 0.8rem;
      font-weight: 600;
      margin-bottom: 0.75rem;
    }

    .label-valid { background: #dcfce7; color: #166534; }
    .label-invalid { background: #fee2e2; color: #991b1b; }

    pre {
      background: #f1f5f9;
      padding: 1rem;
      border-radius: 6px;
      font-size: 0.85rem;
      overflow-x: auto;
      margin-bottom: 0.75rem;
    }

    .note {
      color: var(--muted);
      font-size: 0.9rem;
    }

    .results {
      margin-top: 2rem;
      padding: 1rem;
      background: #dbeafe;
      border: 1px solid #93c5fd;
      border-radius: var(--radius);
    }

    .results h3 { margin-bottom: 0.5rem; }

    #validationOutput {
      margin-top: 0.5rem;
      font-family: monospace;
      white-space: pre-wrap;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>规范验证:元素嵌套规则</h1>

    <div class="example valid">
      <span class="label label-valid">有效</span>
      <h3>section 内部包含 h2 和 p</h3>
      <pre>&lt;section&gt;
  &lt;h2&gt;标题&lt;/h2&gt;
  &lt;p&gt;内容&lt;/p&gt;
&lt;/section&gt;</pre>
      <p class="note">section 的内容模型为 Flow content,h2 和 p 都是流内容。</p>
    </div>

    <div class="example invalid">
      <span class="label label-invalid">无效</span>
      <h3>p 内部包含 div</h3>
      <pre>&lt;p&gt;
  &lt;div&gt;内容&lt;/div&gt;
&lt;/p&gt;</pre>
      <p class="note">p 的内容模型为 Phrasing content,div 是 Flow content,不允许嵌套。
      浏览器会自动关闭 p 标签。</p>
    </div>

    <div class="example valid">
      <span class="label label-valid">有效</span>
      <h3>a 内部包含 span 和 strong</h3>
      <pre>&lt;a href="#"&gt;
  &lt;span&gt;文本&lt;/span&gt;
  &lt;strong&gt;加粗&lt;/strong&gt;
&lt;/a&gt;</pre>
      <p class="note">a(交互内容)可以包含 Phrasing content。
      span 和 strong 都是短语内容。</p>
    </div>

    <div class="example invalid">
      <span class="label label-invalid">无效</span>
      <h3>a 内部包含另一个 a</h3>
      <pre>&lt;a href="#"&gt;
  &lt;a href="#"&gt;嵌套链接&lt;/a&gt;
&lt;/a&gt;</pre>
      <p class="note">Interactive content 不能包含另一个 Interactive content。
      浏览器会自动关闭第一个 a 标签。</p>
    </div>

    <div class="example valid">
      <span class="label label-valid">有效</span>
      <h3>details 内部包含 summary 和 div</h3>
      <pre>&lt;details&gt;
  &lt;summary&gt;标题&lt;/summary&gt;
  &lt;div&gt;详细内容&lt;/div&gt;
&lt;/details&gt;</pre>
      <p class="note">details 的内容模型:一个 summary + Flow content。</p>
    </div>

    <div class="results">
      <h3>浏览器实际解析结果</h3>
      <p>打开 DevTools → Elements 面板,查看浏览器如何实际解析上述嵌套结构。</p>
      <button onclick="checkParsing()" style="
        margin-top: 0.5rem;
        padding: 0.5rem 1rem;
        background: var(--primary);
        color: white;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 0.95rem;
      ">检查 DOM 结构</button>
      <div id="validationOutput"></div>
    </div>
  </div>

  <script>
    function checkParsing() {
      var output = document.getElementById('validationOutput');

      // 创建临时容器来检查浏览器的实际解析
      var testCases = [
        { name: 'p > div', html: '<p><div>test</div></p>' },
        { name: 'a > a', html: '<a href="#"><a href="#">test</a></a>' },
        { name: 'li > div', html: '<ul><li><div>test</div></li></ul>' },
        { name: 'button > div', html: '<button><div>test</div></button>' }
      ];

      var results = [];
      testCases.forEach(function (tc) {
        var container = document.createElement('div');
        container.innerHTML = tc.html;
        var parsedHTML = container.innerHTML;
        results.push(
          tc.name + ':\n  输入: ' + tc.html + '\n  解析: ' + parsedHTML
        );
      });

      output.textContent = results.join('\n\n');
      console.log('DOM 解析结果:', results);
    }
  </script>
</body>
</html>

注意事项

  • 规范文档非常长:HTML Living Standard 全文有数万行,不要试图从头读到尾,按需查阅
  • 规范语言严格且抽象:规范使用形式化语言描述行为,初读时可能感到晦涩,需要多练习
  • 规范是英文文档:目前 WHATWG 规范仅有英文版本,阅读时可以借助浏览器翻译
  • 规范可能更新:规范文档随时更新,如果你在讨论中引用规范,建议注明日期或使用永久链接(Permalink)
  • 浏览器可能有偏差:浏览器的实现可能与规范不完全一致,遇到差异时应参考浏览器行为

最佳实践

  • MDN 是日常开发的最佳参考:MDN 基于规范编写,语言更友好,还有丰富的示例和浏览器兼容性数据
  • 遇到争议时查阅规范原文:当对某个行为不确定时,规范的原文是最权威的解答
  • 关注规范更新:定期查看 WHATWG 的 GitHub 仓库了解最新的变更和讨论
  • 理解内容模型:掌握 HTML 元素的内容类别和嵌套规则,能有效避免 DOM 解析错误
  • 使用 HTML 验证工具:W3C 提供在线 HTML 验证器(https://validator.w3.org/),可以检查 HTML 是否符合规范

下一节

继续学习:浏览器兼容性

参考链接