有人给我看过一个 .html 文件,从头到尾只有几行:
<p>hello
存成 a.html,双击打开,正常显示。F12 看 Elements 面板,里面有完整的结构:
<html>
<head></head>
<body>
<p>hello</p>
</body>
</html>
这几层不是我写的,是 HTML 解析器在插入阶段补出来的。规范里明写了 html、head、body 的起止标签可以省略,解析器按固定规则补齐。所以”能不能省”这件事,答案是能,而且省了也不会出问题。
但另外两样省了会出问题,代价还不一样。
doctype:省掉就退回怪异模式
把 <!DOCTYPE html> 删掉,页面通常还是能看——直到你遇到某个宽度算不准、行高奇怪的地方。判断自己在哪个模式,一行就够:
document.compatMode
返回 "CSS1Compat" 是标准模式,返回 "BackCompat" 是怪异模式(quirks mode)。有 doctype 是前者,没有是后者。
怪异模式不是”兼容 IE6 的怀旧开关”,它会改一批盒模型相关的默认值。最直观的一条:怪异模式下 box-sizing 的初始值相当于 border-box,标准模式下是 content-box。也就是说同一个 width: 200px; padding: 10px,在两种模式下外框宽度一个 200、一个 220。
所以 doctype 这 15 个字符是整个文件里性价比最高的一行——它决定了后面所有尺寸计算的基准。
charset:位置比内容更容易出事
<meta charset="utf-8"> 的规范要求是:整个编码声明必须落在文档的前 1024 字节内。原因不复杂——浏览器开始解析时还没读完整个文件,它必须在某个点之前知道该用什么编码解码,否则只能先猜。
把 charset 挪到一坨注释后面,让它的字节位置超过 1024,会怎样?现代浏览器的编码嗅探相当聪明,中文环境里经常能猜回 UTF-8,于是你什么都看不到。这条规矩更接近”别去踩”,而不是”踩了必然报错”。真要验证,看这个:
document.characterSet // "UTF-8"
它告诉你浏览器最终用了什么编码解码这个文档,比肉眼看有没有乱码可靠。
lang:影响字形,不是影响翻译
<html lang="zh-CN"> 最容易被当成 SEO 用的元数据。它真正的作用有几个,都和”渲染出来长什么样”直接相关:
- 汉字字形选择。 中日韩共用大量码位,但字形不同——”直”字在日本字体里下部是竖直的,在中国字体里带一个小横。同一个 Unicode 码位,
lang="ja"和lang="zh-CN"可能渲染出两个字。 - 断行规则。 不同语言允许断开的位置不一样,浏览器按
lang选断行字典。 - 读屏发音。 屏幕阅读器按
lang切换语音库。整页写lang="en"的中文页面,读屏会用英文音库念中文,基本没法听。
最后这条是我改这个站的 lang 的原因。它不影响任何视觉,但决定了一个用读屏的人能不能听懂这个页面。
我的做法
骨架我现在还是全写。省下那几十个字节换不来任何东西,而多写一行 <html lang="zh-CN"> 能改变字形和读屏输出。能省 ≠ 值得省——这两件事在 HTML 里经常被混为一谈。