<!DOCTYPE html> 是什么
<!DOCTYPE html> 是 doctype 声明:HTML 文件的第一行,位于 <html> 标签之前。它告诉浏览器“这是一个现代 HTML 文档”,浏览器随之用标准模式渲染页面,遵循当前的 HTML 和 CSS 规范。
这一行就是完整的 HTML5 doctype。它没有结束标签,里面也不再放任何东西。
语法规则
- 它必须在最前面。 它前面只能有空白和注释。doctype 之前出现任何文字或标签,浏览器都会忽略它。
- 它不区分大小写。
<!DOCTYPE html>和<!doctype html>完全相同。选一种写法并保持一致。 - 它不是元素。 没有
</!DOCTYPE>,也不能给它加class或其他属性。 - DOCTYPE 后面的单词必须是
html。<!DOCTYPE html5>并不是更新的版本;浏览器会把这样的页面当作没有有效的 doctype。 - 每个文档只有一个。 由多个文件(模板、引入文件)拼成的页面,最终输出的 HTML 顶部也只有一个 doctype。
标准模式和怪异模式
浏览器有三种渲染模式,由 doctype 决定使用哪一种:
| 模式 | 触发条件 | 有什么变化 |
|---|---|---|
| 标准模式 | <!DOCTYPE html> 和其他现代 doctype | 一切都遵循当前规范 |
| 有限怪异模式 | 带 URL 的 HTML 4.01 Transitional 或 Frameset,XHTML 1.0 Transitional 或 Frameset | 几乎等同标准模式:只有一条行高规则不同,所以单独占一行的图片(通常在表格单元格中)下方没有空隙 |
| 怪异模式 | 没有 doctype、doctype 拼错,或某些旧 doctype,例如不带 URL 的 HTML 4.01 Transitional | 模仿 20 世纪 90 年代的浏览器:百分比高度、表格文字大小和行高的表现都不同 |
怪异模式的存在,是为了让 Web 标准出现之前写的页面仍然保持作者当年看到的样子。对新页面来说它只会带来麻烦:height: 100% 在一个页面上有效、在另一个页面上无效,或者表格无视你设置的字号,这些都是缺少 doctype 的典型症状。
本页的编辑器预览总是以标准模式渲染,所以在那里删掉 doctype 并不会让你看到怪异模式。下面的检测工具使用 DOMParser,它采用的规则和浏览器加载文件时相同。在文本框里修改 doctype,模式就会随之更新:
试试删掉这一行、输入 <!DOCTYPE html5>,或者在 doctype 前面加一个单词:每一种都会让结果变成怪异模式。
旧式 doctype:HTML 4.01 和 XHTML
在 HTML5 之前,doctype 会用一个很长的公共标识符指定一个 DTD 文件。在较老的网站顶部仍然能看到它们:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
浏览器从来不会下载这些 DTD 文件。它们只读取标识符来选择模式:HTML 4.01 Strict 和 XHTML 1.0 Strict 对应标准模式,Transitional 版本对应有限怪异模式,不带 URL 的 HTML 4.01 Transitional 对应完全的怪异模式。把其中一个粘贴到上面的检测工具里试试;注意,compatMode 把有限怪异模式报告为 CSS1Compat,和标准模式的值相同,所以只有完全的怪异模式才会显示为 BackCompat。
对于已经处于标准模式的页面,把旧 doctype 换成 <!DOCTYPE html> 是安全的。原本处于怪异模式的页面可能会有些许变化(通常是高度和图片下方的空隙),所以改完之后检查一遍。
DOM 中的 doctype
doctype 会变成一个 DocumentType 节点,和 <html> 元素分开。脚本通过 document.doctype 读取它,document.compatMode 则报告页面最终所处的模式:
document.compatMode 是检查任何线上网站最快的方法:打开浏览器控制台输入它即可。"CSS1Compat" 表示标准模式(或有限怪异模式),"BackCompat" 表示怪异模式。
完整的 HTML5 起始模板
doctype 是每个页面都应该采用的最小文档的一部分。下面每一行都有各自的作用:
lang 属性和 meta viewport 标签各有专门的页面介绍。
常见错误
- doctype 前面有内容。 一个多余的字符、服务器脚本里调试用的
echo,或者<!DOCTYPE html>上方的 HTML 标签,都会让整个页面进入怪异模式。注释和空行没有问题。 - 自创版本号。
<!DOCTYPE html5>或<!DOCTYPE HTML 5>都无效,会触发怪异模式。HTML5 的 doctype 就是<!DOCTYPE html>。 - 给它加结束标签。
<!DOCTYPE html></!DOCTYPE>不是有效的 HTML。这个声明没有结束标签。 - 在小测试文件里省略它。 你在没有 doctype 的草稿文件里追查的布局 bug,在真实页面中可能并不存在,反之亦然。
- 保留旧的 Transitional doctype。 它让页面进入有限怪异模式,却没有任何好处。请换成
<!DOCTYPE html>。
常见问题
<!DOCTYPE html> 有什么作用?
它告诉浏览器这个页面是现代 HTML 文档,于是浏览器用标准模式渲染。没有它,浏览器会退回到怪异模式,这种模式模仿 20 世纪 90 年代末浏览器的 bug,会改变某些布局和高度的计算方式。
<!DOCTYPE html> 是必需的吗?
没有它页面照样能加载,但 HTML 标准要求写它,而且浏览器会用怪异模式渲染页面。一定要把 <!DOCTYPE html> 放在第一行。
doctype 区分大小写吗?
不区分。<!DOCTYPE html>、<!doctype html> 和 <!DocType HTML> 的意思完全一样。最常见的写法是大写的 DOCTYPE 加小写的 html。
DOCTYPE 是 HTML 标签吗?
不是。它是一个声明,不是元素:它没有结束标签,不能添加属性,也不会出现在 document.body 中。在 DOM 里,它是一个单独的 DocumentType 节点,可以通过 document.doctype 访问。
HTML5 的 doctype 是什么?
<!DOCTYPE html>。HTML5 去掉了 HTML 4.01 和 XHTML 中冗长的公共标识符和 URL,任何新页面都只需要这个简短的 doctype。
怎样检查页面是否处于怪异模式?
打开浏览器控制台,运行 document.compatMode。"CSS1Compat" 表示标准模式(或有限怪异模式),"BackCompat" 表示怪异模式。