When question comes

你一定在 HTML 页面最前面看到过这样一行代码(比如 百度):

<!DOCTYPE html>

或者说类似这样的(比如 博客园-韩子迟 PS:博客园首页 文档类型声明同百度):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

那么问题来了。

  • 这行代码有什么用?
  • 去掉它会有什么影响?

Standards Mode VS Quirks Mode

要弄清楚这个问题,我们先来解释一下浏览器的 "标准模式"(Standards Mode, 也称 strict mode)和 "怪异模式"(Quirks Mode,有时又称 "混杂模式"、"兼容模式 Compatibility Mode")这两个名词。

什么是 Quirks Mode? 简单来说,Quirks Mode 就是浏览器为了兼容很早之前针对旧版本浏览器设计、并未严格遵循 W3C 标准的网页而产生的一种页面渲染模式

我们以 IE 为例。随着 IE 的发展,其渲染引擎(早期为 MSHTML.dll,后来命名为 Trident)也在不断加入新的特性以及修正一些早先版本的错误。在 2001 年 IE6 正式发布之前,当时的市面主要就是 IE 和 Netscape 的 Navigator 两款浏览器,而 IE 拥有很大的用户群,所以大多数的页面都是针对 IE 而设计的,但是 IE 的渲染引擎却没有遵循 W3C 的规范,当时微软已经认识到 W3C 规范的重要性,所以当 IE 发展到 IE6 的时候,渲染引擎(MSHTML.dll)做出了一个重要的改变,将自己原先不符合 W3C 规范中的盒模型 box mode 绘制方式改为与 W3C 标准一致,由于这个重大的改动,原先针对 IE 旧版本所设计的 HTML 页面都不能正确显示了,所以在 IE6 发布的时候附带了一个切换回 IE5(准确地说应该是 IE5.5) 页面渲染方式的功能,这个功能中就首次提出了 Quirks Mode。

当用户需要显示旧版本的页面时切换到 Quirks Mode,这时浏览器的渲染引擎就切换到 IE5.5 所对应的版本(MSHTML.dll 5.5.x),box mode 还是按照之前的方式绘制,这样页面就可以正确显示。当用户需要显示一些新的、满足 W3C 规范的页面时,渲染引擎切换到一个与 Quirks Mode 对应的 Standards Mode(标准模式),在此模式下渲染引擎就是当前的最新版本,这样也就满足了更多的 W3C 规范。这两种 Mode 之间的差别就是因为工作在不同版本的渲染引擎环境下。

最后,Quirks Mode 和 Standards Mode 合起来就称为浏览器的文档模式 Document Mode。

实际上,在上文提到的具有 Quirks 和 Standards 两种文档模式的浏览器中还存在第三种模式—Almost Standards Mode。这种模式和 Standards Mode 几乎一致,唯一的区别就在于某些情况下 Almost Standards Mode 会采用与 Quirks 相同的方式来绘制页面。比如当我们需要把图片分割后显示在一个表格单元中时,Almost Standards Mode 与 Quirks Mode 采用同样的绘制方式从而让图片显示不像在 Standards Mode 中那么的四分五裂。

但是这只是极少数的情况,在大部分情况下 Almost Standards 和 Standards 两种模式是一致的,所以我们一般不专门区分二者。

小知识:

  • 一说世界上第一款拥有两种渲染模式的浏览器为 IE6,另一说是 IE5 for Mac,你没有看错,Safari(2003 - ?) 之前,IE 作为 Mac 默认浏览器甚至长达 6 年(1997 - 2003, 2003 中止开发,2006 中止下载)
  • Quirks Mode 有两种。如果我们将 IE 升级到 IE10 就会发现 IE10 除了拥有 IE7/8/9/10 Standards Mode 四种 Standards Mode,同样还有拥有了两种 Quirks Mode:IE5 Quirks 和 IE10 Quirks。随着 IE10 发布而产生的这个新的怪异模式 IE10 Quirks 被认为是一种更好的支持了 HTML5 规范的 Quirks Mode。我们可以发现针对 HTML5 规范而设计的页面(如含有 <audio><video><canvas> 等标签)在 IE5 Quirks 下是不能正确显示的,但是在 IE10 Quirks 下完全可以正确显示。也就是说,IE10 Quirks 是为了在那些针对 HTML5 设计,但是又没有添加 doctype 的页面而存在的。

DOCTYPE

上面我们说到当时 IE6 的渲染为了既能遵循 W3C 标准,又能保证旧的网页能继续浏览,这样浏览器上就产生了 Quircks mode 和 Standars mode 两种渲染模式,两种渲染方法共存在一个浏览器上。但是手动切换显然是不切实际的,微软提出了文档类型(DOCTYPE)这个当时非常 "新颖" 的概念。

一个网页,如果没有指明文档类型(旧的网页根本没文档类型一说),那么浏览器自动采用 "怪异模式" 去渲染页面,如果指明了文档类型,就按照文档指明的类型进行渲染。所以,如果你的网页没有声明文档类型,那么就会用浏览器的 "怪异模式" 去解析你的页面,这是非常危险的!而两个模式对页面解析最大的区别无疑是对于盒模型的解析。

这里我们不会去分析怪异模式和标准模式在页面渲染方面会有多少的不同之处坑爹之处,为了能有个感性的认识,我举个简单的例子。

我从网上找了个俄罗斯方块的 游戏代码,带有 DTD 的效果猛戳 这里,去除 DTD 的效果猛戳 这里

IE(无 DTD 声明的网页):

Firefox(无 DTD 声明的网页,chrome 的怪异模式渲染效果和 ff 类似):

很显然,没有 DTD 声明,浏览器进入怪异模式渲染页面,所以页面乱了。而且 IE 和 FF 怪异模式渲染效果不一样,这也很好理解,毕竟没遵循 W3C 标准前,每家的标准都有自己一套。在 FF 的页面可以右键查看其 Page Info。

那么浏览器究竟该采用哪种 DTD 渲染页面呢?推荐使用:

<!DOCTYPE html>

经过调研,BAT 以及 GOOGLE 等大公司用的都是它,能很好地向后兼容。所以,放心大胆地用它吧!

其他各种文档类型声明以及差异可以参考 HTML 标签

声明必须是 HTML 文档的第一行,位于 <html> 标签之前。

声明不是 HTML 标签,它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。

在 HTML 4.01 中, 声明引用 DTD,因为 HTML 4.01 基于 SGML。DTD 规定了标记语言的规则,这样浏览器才能正确地呈现内容。HTML5 不基于 SGML,所以不需要引用 DTD。

小知识:

  • 在 ie6 中,如果在 doctype 声明前有一个 xml 声明(比如: <?xml version="1.0" encoding="iso-8859-1"?>),则采用 quirks mode 解析。这条规则在 ie7 中已经移除了。

Back to the question

我们再回到这个问题,浏览器从服务端获取网页后会根据文档的 DOCTYPE 定义显示网页,如果文档正确定义了 DOCTYPE 浏览器则会进入标准模式(Standards Mode),否则浏览器会认为你的网页是旧的网页(需要用旧的渲染引擎去解析),从而进入怪异模式(Quirks mode)进行解析。

为了避免浏览器进入怪异模式(事实上,现实中已经几乎没有网页需要用浏览器的怪异模式去解析,浏览器的 Quirks Mode 仅仅是为了向后兼容),所以,请确保在 HTML 页面的首行写上:

<!DOCTYPE html>

Read More:


2016.11.05 补一张图:

前端科普文—为什么<!DOCTYPE> 不可或缺的更多相关文章

  1. React半科普文

    React半科普文 什么是React getting started 文件分离 Server端编译 定义一个组件 使用property 组件嵌套 组件更新 Virtual DOM react nati ...

  2. 【轻松前端之旅】<!DOCTYPE>标签

    前端学习,先学习HTML,CSS,Javascript HTML - HyperText Markup Language HTML-超文本标记语言,提供了一种标记网页内容的方法. 浏览器怎么知道如何显 ...

  3. Hadoop科普文——常见的45个问题解答(CSDN)

    Hadoop科普文——常见的45个问题解答 1.Hadoop集群可以运行的3个模式? 单机(本地)模式 伪分布式模式 全分布式模式 2.  单机(本地)模式中的注意点? 在单机模式(standalon ...

  4. Vue 2.5 发布了:15篇前端热文回看

    Vue 2.5 发布了:15篇前端热文回看 2017-11-02 前端大全 (点击上方公众号,可快速关注) 本文精选了「前端大全」2017 年 10 月的 15 篇热门文章.其中有职场分享.技术分享和 ...

  5. 前端 HTML文档 详解

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 科普文:从人人网看网络科学(Network Science)的X个经典问题

    转:https://zr9558.wordpress.com/2013/12/05/科普文:从人人网看网络科学(network-science)的x个经典问/ 长文,写了N个小时写完的.你肯定能看懂, ...

  7. 6 大主流 Web 框架优缺点对比:15篇前端热文回看

    摘自:http://blog.csdn.net/VhWfR2u02Q/article/details/78993079 注:以下文章,点击标题即可阅读 <6 大主流 Web 框架优缺点对比> ...

  8. 前端 HTML文档结构介绍

    <!DOCTYPE HTML> <html> <head>...</head> <body>...</body> </ht ...

  9. 科普文:Node.js 如何上传文件到后端服务【转】

    原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload 背景 互联网时代,无数服务是基于 HTTP 协议进行通信的. 除了常见的 前端浏览器 - ...

随机推荐

  1. PreferenceScreen监听子项的刷新

    有个PreferenceScreen,他有一些个子项目.它的Summary需要根据子项的设置来改变的,所以需要监听子项的刷新事件. preferenceScreen.setOnPreferenceCh ...

  2. Lojic X

    媒体 赫兹 电话  500HZ 网络数据 8000HZ CD  44100HZ  电脑 48000HZ DVD 96000HZ 最大值(蓝光) 192000HZ   横向———————— 清晰度   ...

  3. mybatis 中#{}与${}的区别

    1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111&qu ...

  4. 0005 《SQL必知必会》笔记01-SELECT语句

    1.SELECT基本语句: SELECT 字段名1,···,字段名n FROM 表名 2.检索所有字段,用"*"替换字段名,这会导致效率低下 SELECT * FROM 表名; 3 ...

  5. 万能面试问题大全,教你怎么回答,怎么拿下offer

    一.你对薪资的要求? 回答提示: 说实话,大家找工作,都希望找个高薪的,那我们如何和公司去谈薪酬呢?如果你对薪酬的要求太低,那显然贬低自己的能力:如果你对薪酬的要求太高,那又会显得你分量过重,公司受用 ...

  6. android中的数据存取-方式一:preference(配置)

    这种方式应该是用起来最简单的Android读写外部数据的方法了.他的用法基本上和J2SE(java.util.prefs.Preferences)中的用法一样,以一种简单. 透明的方式来保存一些用户个 ...

  7. android 动态设置Framelayout,view,imageView,Layout高度

    直接:测试可以 Framelayout.getLayoutParams().width=600;Framelayout.getLayoutParams().height=400; 如:view,ima ...

  8. WCF自定义Header

    MiscWebSrvcInfClient client = new MiscWebSrvcInfClient("MiscWSBeanPort", ConfigurationMana ...

  9. c++关于析构的那点小事(个人吐槽向

    #include<iostream> using namespace std; class test { int *i; public: test(int n) { i = new int ...

  10. Caffe源码解析1:Blob

    转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ 首先看到的是Blob这个类,Blob是作为Caffe中数据流通的 ...