01|HTML5 最像的,不是新版本发布,而是朝廷终于决定招安山头

很多人第一次听到 HTML5,记住的是这些名字:

  • video
  • audio
  • canvas
  • header
  • section

这当然没错。

但如果你把 HTML5 理解成“HTML 4 的升级包”,那你会漏掉它最狠的一刀。

那一刀不是新标签。

而是它开始正式规定:

那些写得乱七八糟、但整个互联网都在跑的 HTML,浏览器到底该怎么处理。

这听起来一点都不性感。

甚至有点像修市政下水道。

可第五篇真正的爆点偏偏就在这里。

它不酷。

但它管命。

可从制度上说,这才是 HTML5 真正改变历史的位置。

因为在它之前,Web 已经形成了一种非常别扭的现实:

  • 规范写的是一套理想
  • 浏览器干的是另一套兜底
  • 作者交上来的页面经常根本不合规范
  • 用户却照样要看新闻、下订单、填表单

于是浏览器只能一边嘴上说“请写规范一点”,一边继续默默替整个互联网收拾残局。

HTML5 真正干的,就是把这批早就占山为王很多年的“野路子”收编进制度。

所以我才说:

HTML5 不是一次升级,而是一次招安。


02|在 HTML5 之前,浏览器最荒唐的工作之一,是互相猜别人怎么吞错

今天很多人习惯把规范想成说明书:

浏览器照着实现。

作者照着写。

大家照着互通。

对当年的 HTML 来说,这种想象太乐观了。

因为到了 HTML 4 / XHTML 那一代,纸面规范越来越像“正确世界应当如何”的文件。

可现实网页常常根本不按那个世界来活。

你会看到:

  • 标签没闭合
  • 嵌套顺序乱了
  • 属性写法不标准
  • 一些历史写法明明不合规范,但全网大量存在

这些东西在验证器眼里是错误。

可在浏览器眼里,它们又不能简单等于“不能显示”。

原因很简单:

浏览器不是只服务作者。

它还服务用户。

作者写坏了页面,用户还是要看内容、买东西、交作业、进后台。

于是浏览器被逼出一种特别狼狈的工作方式:

“你们规范先写着,我先把互联网尽量跑起来。”

更痛苦的是,各家浏览器虽然都在兜底,但兜法又不总一样。

这时候实现者最荒唐的工作之一就出现了:

逆向别的浏览器到底是怎么吞这些错误的。

也就是说,在 HTML5 之前,很多互通性并不是建立在“大家都实现了同一份足够细的规则”上。

而是建立在:

“大家尽量模仿彼此处理脏页面的经验。”

这显然不是长久之计。


03|一开始他们也没想写 parser 宪法,他们只是想给 Web 应用补点东西

这里有个特别容易被忽略的误会。

后来大家回头讲 HTML5,会以为它一开始就奔着“重写解析秩序”去了。

其实不是。

WHATWG2004 年重开 HTML 线时,最初瞄准的重点更像:

  • Web 应用需要的能力
  • 更现实的表单
  • 浏览器里真正会用到的接口

也就是说,起点不是:

“我们来写一部庞大的 HTML 解析宪法。”

起点更像:

“现实 Web 应用已经跑起来了,先把急需的东西往前推。”

可做着做着,他们发现一个要命的问题。

你如果连 HTML 最底层怎么被浏览器读进去、拆开、纠错、长成 DOM 都说不清,上层扩展根本稳不住。

Anne van Kesteren 回顾这段历史时说得非常直白:

一开始大家只是想做一些 HTML 扩展;可随着工作推进,你会意识到,如果不理解 fundamentals,很多扩展根本走不下去。
而 Web 又不可能推倒重来。

这句话几乎把整场戏说透了。

HTML5 后来越写越厚,不是编辑癖发作。

而是:

现实逼着它一路往下钻,直到把原来没人想公开写的脏活也写进去。


04|2006 年最关键的一回合,是 Ian Hickson 真把 parser 用英文长文写出来了

这条线真正开始有戏,是在 2006 年上半年。

Anne 的回顾里提到,Ian Hickson 当时真的用英文 prose 把 HTML parser 写出来了。

这事听上去像学术苦工。

可在当时,它简直像在干一件很多人觉得不可能的事。

因为浏览器解析 HTML 的复杂度早就臭名昭著。

你要把这套东西从:

  • 工程师脑子里的经验
  • 浏览器源码里的私房逻辑
  • 各家互相猜出来的隐形默契

变成一份能公开讨论、能逐条实现、能被测试套件验证的文字规则,这件事听起来就很疯狂。

Anne 还顺手记了一笔现场反应。

Dave Hyatt 当时就怀疑:这玩意儿的复杂度,我们真能准确写下来吗?

这句怀疑特别有画面。

它说明连实现者都知道自己面对的是一团多难收拾的旧账。

可很快,第一批小胜利就来了。

Anne 写道,WebKit 曾经仅仅因为看了 HTML5 parser draft,就修掉了一个 bug;Opera 也因为跟着规范走,修掉了不少解析互通问题。

这一下,局势变了。

原来那套长期被当成浏览器私房手艺的东西,一旦写成规则,真的能减少大家继续互猜彼此。

这就是 HTML5 最像“招安”的瞬间。

原先散落山头、各家秘传的活法,第一次被往中央秩序里编。


05|后来被招安的,不只是功能,还有那一堆脏页面的活法

如果要用一句话概括 HTML5 的制度转向,我会这么说:

它第一次非常认真地承认:坏网页不是边角料,而是 Web 现实的一部分。

这不是鼓励作者乱写。

这里必须分清两层。

规范仍要求作者写对

规范当然还是希望你写得更对、更干净、更符合约定。

但浏览器必须先接住坏页面

浏览器不能只处理“写得对的页面”。

它还必须处理:

  • 历史页面
  • 坏掉的页面
  • 老工具吐出来的页面
  • 看上去不合规范、但全网大量存在的页面

这也是为什么 HTML Design Principles 会特别强调:

  • Support Existing Content
  • Pave the Cowpaths
  • Evolution Not Revolution
  • Handle Errors

这几条放一起,意思已经非常明显了。

Web 标准不能只服务理想作者,它还必须服务已经存在的现实内容。

这就是 HTML5 和很多传统版本升级最不一样的地方。

普通升级常常像:

旧世界过去了,新世界来了。

HTML5 不是。

HTML5 的逻辑更像:

旧世界不会自己消失。

既然如此,就别假装它不存在,而是把它纳入规则,至少让各家浏览器在“怎么继续救它”这件事上别再各救各的。


06|真正改变游戏规则的,不是宽容,而是把宽容写成可互通的法律

很多人会把 HTML5 的精神概括成“宽容错误”。

这话只说对了一半。

如果只是宽容错误,那浏览器早就在这么干了。

HTML5 真正干的,是更难的一步:

把宽容变成可预测、可实现、可测试、可互通的宽容。

这差别非常大。

模糊的宽容意味着:

  • 你知道浏览器大概会救
  • 但不知道它具体怎么救
  • 不同浏览器可能救出不同结果

可互通的宽容意味着:

  • 你知道浏览器必须按什么规则救
  • 你知道不同实现应尽量得到同样结果
  • 你知道测试、validator、实现者能围绕同一套规则工作

这就是为什么 HTML5 看上去像在向坏代码低头,实际上却是在做一件非常秩序化的工程工作:

把原本口耳相传、实现各异的容错行为,压成一套正式制度。

所以 HTML5 不是“规范放弃原则”。

更准确地说,它是在重划原则:

  • 对作者,继续鼓励干净写法
  • 对浏览器,必须要求你面对现实世界的脏内容,并尽量统一地处理

07|这件事为什么不只是照顾旧网页,而是在改写开放 Web 的治理方式

Anne 那篇回顾里还有一层特别重要。

在 parser spec、测试、实现、validator 一起演进之后,大家不再需要靠逆向别的浏览器来做事;这会降低新玩家进入门槛,也能避免新的浏览器单一化。

这句话很重。

因为它说明 HTML5 做这件事,不只是为了“照顾老网页”。

它还有更深的一层:

把过去全靠大厂经验和私房知识维持的兼容性,尽量公共化、制度化。

这会直接影响:

  • 浏览器互通
  • 测试体系
  • 新实现者进入成本
  • Web 平台是不是继续被少数既有实现绑住

再往后看,html5lib、测试套件、Validator.nu、Firefox 新 parser 一起演进的那条线,也都说明同一件事:

HTML5 的 parser 和错误处理规则,表面上像旧账整理。

往深了看,它其实是在重写开放 Web 的底层治理方式。


08|所以 HTML5 真正升级的,不是标签,而是标准面对现实的胆量

这也是我一直觉得:

把 HTML5 理解成“加入了一堆现代特性的 HTML 新版本”,其实太轻了。

它当然加了很多东西。

但它更大的动作,是把标准的姿态改了。

在它之前,标准更像一份“正确世界应当如何”的说明书。

在它之后,至少在 HTML 这条线上,标准越来越像一份:

既描述理想,也接管现实;既指导作者,也约束实现;既看未来,也不敢假装历史不存在的宪法。

这也是 HTML5 和 XHTML 路线最大的区别之一。

XHTML 更像:

我先把纪律定好,你们按纪律来。

HTML5 更像:

我先承认你们实际上就是这么活的,然后尽量把这套活法整理成可互通、可维护、可继续演进的秩序。

前者更纯。

后者更像 Web。


09|HTML5 真正升级的,是标准开始下场接管现实

今天回头看,HTML5 最值得记住的,也许并不是当年宣传里最红的功能名。

真正让它和前代分开的,是这一步:

它不再试图把现实网页排除在标准之外,而是决定让标准自己下场,去接管现实。

这就是为什么我会说:

HTML5 不是一次升级,而是一次招安。

它招安的,不只是新能力。

它招安的还有:

  • 老页面
  • 坏页面
  • 历史包袱
  • 浏览器长期私下承担的兜底责任
  • 整个 Web 世界已经形成、却一直没有被正式承认的活法

这件事一点都不浪漫。

但它非常像开放 Web。

因为开放 Web 最终能活下来的,从来不只是最漂亮的方案。

更常见的情况是:

谁能把已经存在、已经依赖、已经甩不掉的现实,整理成一套勉强还能继续演进的秩序,谁就更接近真正的标准。


编者注(事实核对):文中关于 2006 年 Ian Hickson 以英文 prose 写 parser 草案、Dave Hyatt 对其复杂度表示怀疑、WebKit 与 Opera 因 parser draft 修复兼容问题、html5libValidator.nu 和 Firefox 新 parser 共同演进等细节,主要依据 Anne van Kesteren 的《Notes on HTML5 Parser History》。关于 Support Existing ContentPave the CowpathsHandle Errors 等原则,则主要依据 HTML Design Principles


关键人物速览

  • Ian Hickson:HTML5 parser 这条线上的关键人物。第五篇里那场“把浏览器私下默契写成公开规则”的硬活,绕不开他。
  • Anne van Kesteren:HTML parser 历史的重要亲历者与回顾者。很多关于 parser 草案、互通 bug 和规范如何真正接管现实的细节,都来自他的记录。
  • Dave Hyatt:浏览器实现者一侧的重要声音。第五篇里“这复杂度真能写准吗”的怀疑,特别能说明当年这件事有多难。
  • Henri Sivonen:Firefox 新 HTML5 parser 这条线上的关键实现者之一。理解 HTML5 parser 如何从文稿变成真正 shipping 的现实能力时,绕不开他。

参考与延伸阅读

  1. HTML Design Principles
    https://www.w3.org/TR/html-design-principles/

  2. WHATWG HTML Standard Introduction
    https://html.spec.whatwg.org/multipage/introduction.html

  3. HTML Standard Parsing
    https://html.spec.whatwg.org/multipage/parsing.html

  4. HTML5 Differences from HTML4
    https://www.w3.org/TR/html5-diff/

  5. Notes on HTML5 Parser History
    https://annevankesteren.nl/2010/05/html5-parser-history

  6. Hixie: Tag Soup - Crazy parsing adventures
    https://ln.hixie.ch/?count=1&start=1137740632