📘 第十章 构建Web内容的技术
📄 一句话概括

doctype 那行不只是「声明版本」,它还决定浏览器用标准模式还是怪异模式排版。 HTML5 敢把它从 121 字节砍到 15 字节,因为它不再基于 SGML。

📝 本节和前面几节的关系

上一节看了页面长什么样,这一节看它的「出生证明」。 一行 15 个字节的声明,背后是二十年的版本更迭。

一、doctype 干两件事

第一件是明面上的:告诉浏览器「这份文档按哪个版本的规矩写」。 HTML 4.01 要写一长串 DTD 地址,XHTML 1.0 更长。 第二件是暗地里的,也是更要命的一件:决定渲染模式。 有 doctype 就走标准模式(standards mode),一个都不写就退回怪异模式(quirks mode)。 两种模式下,盒模型的计算方式、行高的继承方式都不一样。 所以「删了 doctype 页面就错位」不是玄学,是浏览器故意在兼容九十年代的老页面。

二、从两行到一行

Demo 量了三种写法:HTML5 那行 15 字节,HTML 4.01 Strict 90 字节, XHTML 1.0 Transitional 121 字节。最长的那行是 HTML5 的 8 倍。 HTML5 为什么敢全删?因为它不再基于 SGML。 早期 HTML 是 SGML 的一个应用,所以必须有 DTD 声明「用哪套语法」; HTML5 另起炉灶定了一套自己的解析规则,DTD 就没用了。 删掉之后还顺手解决了一个老问题:浏览器不用再去下载那个 DTD 地址。 虽然实际上没人真去下,但那一长串地址在每一页里都占着字节。

三、XHTML 那条岔路

2000 年前后,W3C 想把 HTML 拉回 XML 的严格语法:标签必须闭合、属性必须加引号、大小写必须小写。 这一支叫 XHTML。 方向不难理解——严格的语法机器好处理。 但代价是人写得难受:少一个 / 整页就报错,浏览器干脆什么都不显示。 结果是 HTML5 这条线赢了:它承认「网页是人手写的,一定会出错」,所以解析器要尽量容错。 今天的浏览器里,XHTML 那条线基本只剩历史意义。 版本年表:HTML 2.0(1995)、HTML 3.2(1997)、HTML 4.0(1997)、HTML 4.01(1999)、 XHTML 1.0(2000)、HTML5(2014 年成为 W3C 正式推荐)。

四、动手 Demo:三种 doctype,量长短、看解析结果

把三种 doctype 摆在一起量字节,再用解析器看它到底被认成了什么。顺便把版本年表列出来。

DOCTYPES = [
    (u"HTML5", u"<!DOCTYPE html>"),
    (u"HTML 4.01 Strict",
     u'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'
     u' "http://www.w3.org/TR/html4/strict.dtd">'),
]

实跑输出:

--------------------------------------------------------------------
doctype 的三种写法:长短差多少
--------------------------------------------------------------------
  版本                       字节      写法
  HTML5                    15      <!DOCTYPE html>
  HTML 4.01 Strict         90      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTM…
  XHTML 1.0 Transitional   121     <!DOCTYPE html PUBLIC "-//W3C//DTD XHT…

  HTML5 那行                 15 字节
  XHTML 那行                 121 字节
  差了                       8 倍
  HTML5 被解析成             DOCTYPE html
  HTML 4.01 Strict 被解析成  DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://
  XHTML 1.0 Transitional 被解析成 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional/

  HTML5 敢把那两行长 DTD 全部删掉,因为它不再基于 SGML。删掉之后只剩 15 个字节,顺手还解决了另一个老问题:
  doctype 不只是「声明版本」,它还决定浏览器用哪种模式排版。写了 doctype 走标准模式,一个都不写就退回怪异模式(quirks mode),盒模型的计算方式都不一样。
  这一点本机没有浏览器,测不出渲染差异,我只说机制,不给数字。

  版本年表(教材后面的表,这里补上几个关键节点):
  版本           时间             一句话
  HTML 2.0     1995 年 11 月    第一个正式标准(RFC 1866)
  HTML 3.2     1997 年 1 月     表格、脚本、样式开始进来
  HTML 4.0     1997 年 12 月    分离结构与表现
  HTML 4.01    1999 年 12 月    修 bug 的修订版,用了很多年
  XHTML 1.0    2000 年 1 月     用 XML 的严格语法重写 HTML
  HTML5        2014 年 10 月    W3C 正式推荐,doctype 只剩一句

15/90/121 字节,最长的是最短的 8 倍。一行声明省下的字节不多,但它是每一页都要付的。 解析器把它们分别认成 DOCTYPE html、DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ...。 看得出来,HTML5 那行简单到解析器几乎没什么可做的。 HTML5 之后,那串 DTD 地址彻底没用了——因为解析规则不再由 DTD 描述。 这是「规范自己简化自己」的一个少见例子。 渲染模式的差别(标准模式对怪异模式)本机没有浏览器,测不出来,我只说机制: 有没有 doctype 会让浏览器选不同的排版规则表。

30 秒实验

  1. 打开浏览器开发者工具,在控制台输入 document.compatMode,看返回什么。
  2. 把某个页面的 doctype 删掉再看 document.compatMode,对比前后。
  3. 想一想:为什么浏览器要保留「怪异模式」这种反直觉的东西?

常见误区

  1. 「doctype 只是声明版本,没实际作用」——它还决定渲染模式,影响排版。
  2. 「不写 doctype 就是 HTML5」——不写会进怪异模式,恰恰是最糟的情况。
  3. 「XHTML 是 HTML5 的前身」——是另一条岔路,最后被合并掉了。
自测三问(点开对答案) 1. doctype 除了声明版本,还有什么作用? —— 决定浏览器用标准模式还是怪异模式排版。 2. HTML5 的 doctype 为什么能这么短? —— 它不再基于 SGML,不再需要 DTD 声明。 3. XHTML 那条路为什么没走下去? —— 要求太严,人手写容易出错,而浏览器必须容错。

结构定下来了,长相归谁管?下一节看 CSS。

相关笔记