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 秒实验
- 打开浏览器开发者工具,在控制台输入
document.compatMode,看返回什么。 - 把某个页面的 doctype 删掉再看
document.compatMode,对比前后。 - 想一想:为什么浏览器要保留「怪异模式」这种反直觉的东西?
常见误区
- 「doctype 只是声明版本,没实际作用」——它还决定渲染模式,影响排版。
- 「不写 doctype 就是 HTML5」——不写会进怪异模式,恰恰是最糟的情况。
- 「XHTML 是 HTML5 的前身」——是另一条岔路,最后被合并掉了。
自测三问(点开对答案)
1. doctype 除了声明版本,还有什么作用? —— 决定浏览器用标准模式还是怪异模式排版。 2. HTML5 的 doctype 为什么能这么短? —— 它不再基于 SGML,不再需要 DTD 声明。 3. XHTML 那条路为什么没走下去? —— 要求太严,人手写容易出错,而浏览器必须容错。结构定下来了,长相归谁管?下一节看 CSS。
- ☐ (本节完,下一节 10.1.3 设计应用CSS)