热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DOCTYPE与浏览器渲染介绍-

DOCTYPE的诞生DOCTYPE,或者称为DocumentTypeDeclaration(文档类型声明,缩写DTD)。通常情况下,DOCTYPE位于一个HTML文档的最前面的位置,位于根元素HTML的起始标签之前。因为浏览器必须在解析HTML文档正文之前就确定当前文档的类型,以决定其需要采用的渲染模式,不同的渲染模式会影响到浏览器对于CSS代码甚至JavaScript脚本的解析。尤其是在IE系列浏览器中,由DOCTYPE所决定的HTML页面的渲染模

DOCTYPE 的诞生

DOCTYPE,或者称为 Document Type Declaration(文档类型声明,缩写 DTD)。通常情况下,DOCTYPE 位于一个 HTML 文档的最前面的位置,位于根元素 HTML 的起始标签之前。因为浏览器必须在解析 HTML 文档正文之前就确定当前文档的类型,以决定其需要采用的渲染模式,不同的渲染模式会影响到浏览器对于 CSS 代码甚至 Javascript 脚本的解析。尤其是在 IE 系列浏览器中,由 DOCTYPE 所决定的 HTML 页面的渲染模式至关重要。

首先看看当一个 HTML 文档在没有 DOCTYPE 时,页面在各浏览器中会如何渲染及解析。我们尝试生成一个在最顶端没有 DOCTYPE 的 HTML 文档:





这个页面在所有的浏览器中均返回一致的结果,页面上打印出了“BackCompat”。 document.compatMode 属性最初由微软在 IE 中创造出来,这是一个只读的属性,返回一个字符串,只可能存在两种返回值:

  • BackCompat:标准兼容模式(Standards-compliant mode)未开启;

  • CSS1Compat:标准兼容模式已开启。

其实这里所谓的标准兼容模式未开启即“混杂模式”(又叫怪异模式,Quirks mode),标准兼容模式已开启即“标准模式”(又叫严格模式,Standards mode 或者 Strict mode)。 所以前面那个测试样例中,没有书写 DOCTYPE 的 HTML 文档在所有浏览器中均会以混杂模式进行渲染和解析。

注:document.compatMode 在 MSDN 中的介绍:compatMode Property

究竟为何浏览器要制作这么一个“开关”。微软开发的 IE 系列浏览器中寿命最长的 IE6 伴随 Windows XP 诞生。相比上一个版本 IE5.5,IE6 确实有着许多重大的改进,其中对于页面渲染而言最大的变化就在于 IE6 支持了部分 CSS1 中的特性。例如,为一个块级元素设定宽度及高度时,不再作用于 border 外围,而是如 W3C 规范中所描述的仅仅是元素内容之上。这一点和 IE5.5 差别巨大。为了保证那些 90 年代后期的基于 IE6 之前版本开发的页面能够正常显示,即保证浏览器有向后兼容性,此“开关”诞生,微软试图通过对 DOCTYPE 的判断来决定浏览器采取何种模式工作,即是 IE6 还是 IE5.5 的问题。所以从 document.compatMode 返回的字符串值中也可以看出来,BackCompat 代表了向后兼容(即 IE5.5),CSS1Compat 代表了对 CSS1 规范的兼容(即 IE6)。由此,浏览器的工作模式被分为了混杂模式及标准模式。

值得注意的是,IE 的版本号一路从 6.0 升至了目前的 9.0,但升级仅限于标准模式。对于混杂模式,IE 的版本号永久的冻结在 5.5,这也算是为了向后兼容的巨大牺牲。也就是说即使我们使用着最新最高级的 IE9,但若我们不书写 DOCTYPE 或者使用了能够触发混杂模式的 DOCTYPE,那我们所面对的浏览器仍相当于是那个十几年前的老古董 IE5.5。而其他那些浏览器的混杂模式和标准模式之间却没有想 IE 中这么大的差别。

注:IE6 增强的 CSS:CSS Enhancements in Internet Explorer 6

近似标准模式

近似标准模式(Almost Standards Mode)从字面意思上看与标准模式非常类似,但确实有小的差别。主要体现在对于表格单元格内垂直方向布局渲染差异。IE8 开始、Firefox、Chrome、Safari、Opera 7.5 开始,这些浏览器的标准模式更加严格的遵循了 CSS2.1 规范,故对于在目前看来不太“标准”的以前的标准模式,被赋予了“近似标准模式”的名字。但是在较早的 IE6 IE7 以及 Opera 7.5 之前版本中,浏览器无法严格遵循 CSS2.1 规范,故对于它们来说没有这个近似标准模式,也可以理解为它们的近似标准模式就是标准模式。

到目前为止,可以看到各浏览器主要包含了三种模式。在 HTML5 草案中,更加明确的规定了模式的定义:

传统名称HTML5 草案名称document.compatMode 返回值
standards mode 或者 strict modeno-quirks modeCSS1Compat
almost standards modelimited-quirks modeCSS1Compat
quirks modequirks modeBackCompat

注:HTML5 草案关于 compatMode 的介绍:3.1.3 Resource metadata management

DOCTYPE 的选择

工作模式简介

浏览器的工作模式常被称为“渲染模式”。实际上浏览器不同的工作模式不仅对渲染有影响,对代码的解析以及脚本的行为也同样有影响。

从更广泛的角度来看,浏览器的工作模式的差异不仅体现在处理 HTML 页面的时候,处理 XML 及一些非 WEB 内容时也有模式上的差异,但本文仅讨论浏览器在处理 HTML 页面时工作模式。1

注:

  1. 关于浏览器的工作模式的更多信息,请参考 Activating Browser Modes with Doctype。

工作模式的来源及变迁

不使用 DOCTYPE 一定会使 HTML 文档处于混杂模式,然而使用了 DOCTYPE,也不一定就能够使文档在所有浏览器中均处于标准模式。DOCTYPE 本身不就是一个“开关”吗?为何在有 DOCTYPE 的 HTML 文档之上仍然还会出现混杂模式?这个和以下条件有关:

  • 使用了本身就会使浏览器进入混杂模式的古老的甚至是错误的 DOCTYPE;

  • 在 DOCTYPE 之前出现了其他内容,如注释,甚至是 HTML 标签。

我们先说第一个条件。HTML 历史悠久,仅正确的 HTML 类型的 DOCTYPE 就有很多种。先看一个标准的 DOCTYPE:

上面的 DOCTYPE 包含 6 部分:

  1. 字符串“

  2. 根元素通用标识符“HTML”

  3. 字符串“PUBLIC”

  4. 被引号括起来的公共标识符(publicId)“-//W3C//DTD HTML 4.01//EN”

  5. 被引号括起来的系统标识符(systemId)“http://www.w3.org/TR/html4/strict.dtd”

  6. 字符串“>”

其中根元素通用标识符、公共标识符、系统标识符均可以通过脚本调用 DOM 接口获得,分别对应 document.doctype.name、document.doctype.publicId、document.doctype.systemId(IE6 IE7 不支持)。

不同的 DOCTYPE 之间,上面三部分可能不尽相同,有些 DOCTYPE 确实其中某部分,如何在这些纷繁的 DOCTYPE 中选择?

其实浏览器在嗅探 DOCTYPE 时只考虑了上述 6 部分中的第 1、2、4、6 部分,且不区分大小写。在各浏览器内核实现中,几乎都存在一个名单用于记录这些常见的 DOCTYPE 所对应的模式,例如 WebKit 内核中 DocTypeStrings.gperf 文件。各浏览器名单列表中触发模式的不同导致了某些 DOCTYPE 出现在不同浏览器中触发了不同模式的现象,如 。而对于名单之外的 DOCTYPE,浏览器之间处理的差异也会导致触发不同的模式,比如可能有的浏览器会将名单之外的 DOCTYPE 当作混杂模式,而有的却会一律当作标准模式。

所以我们在选用 DOCTYPE 的时候首先确定的是我们想让 HTML 文档使用标准模式。

如果力求最简,则 HTML5 的 DOCTYPE 是最佳选择:,所有的主流浏览器均将这种只包含第 1、2、6 部分的最短的 DOCTYPE 视为标准模式。

如果力求稳妥,则较早的 HTML4.01 Strict 的 DOCTYPE 也是一种好的选择:,它在各主流浏览器中触发的模式与上面的 HTML5 的完全一致。

有时候我们处于特殊情况也希望浏览器能够都处于近似标准模式,则可选择:。

注:关于 Firefox 中 DTD 与浏览器工作模式:Mozilla's DOCTYPE sniffing

DOCTYPE 之前不能出现的内容

前面提到,DOCTYPE 作为一个决定浏览器对于 HTML 文档采取何种模式“开关”,应出现在 HTML 文档的最前面。但有时候处于某些原因,有的作者会在 DOCTYPE 之前防止一些内容,可能是服务端输出的某些信息。这样会让浏览器感到极为“困惑”,它第一眼看到的不是 DOCTYPE,故可能会认为页面没有 DOCTYPE,则可能触发了混杂模式。然而事实上在这一点各浏览器的处理并不相同。我们将 DOCTYPE 之前可能出现的这些内容分类,它们包括:

  • 普通文本

  • HTML 标签

  • HTML 注释

  • XML 声明

  • IE 条件注释

对于普通文本和 HTML 标签,各浏览器均进入了混杂模式,这个很好理解,都看到疑似的 HTML 文档正文了,浏览器不太会往下追查 DOCTYPE 在哪里。

对于 HTML 注释和 XML 声明,它们和上面的普通文本和 HTML 标签有些差别,它们不会在页面中展示出来,即不可视。这时,有的浏览器则显得十分“智能”,非 IE 浏览器均会忽略它们的存在,DOCTYPE 被正确解析。但是在 IE6 中,DOCTYPE 之前的 XML 声明会导致页面进入混杂模式,而所有的 IE 均会使 DOCTYPE 之前出现了 HTML 注释的页面进入混杂模式。在 IE9 中当出现这种情况时,浏览器在控制台中给出了提示:“HTML1113: 文档模式从 IE9 标准 重新启动到 Quirks ”,看来微软在这一点上不打算“随大流”,这样做也可以敦促作者尽量避免在 DOCTYPE 之前加入其他内容。

有的作者很聪明,他既在 DOCTYPE 之前加入了他需要的内容,却又没有使 IE 由于这些内容而进入混杂模式。他可能会这么写:

又或者是

上面这些 IE 条件注释在非 IE 浏览器中,可能完全被忽略,可能被解释为普通 HTML 注释。但是在 IE 中它们全部消失了,因为这就是 IE 条件注释的作用。所以这也是目前比较合适的在 DOCTYPE 之前写点什么又保证所有浏览器均为标准模式的做法,但我们仍然不推荐在 DOCTYPE 之前加入任何非空白内容。

注:关于 IE 条件注释:About Conditional Comments

建议

通过上面的历史回顾以及分析,我们看到了 DOCTYPE 对于目前主流浏览器的关键作用,同时也发掘了能够触发各浏览器标准模式的最佳 DOCTYPE。标准模式会使不同浏览器之间发生兼容性问题的风险降至最低,选择正确的 DOCTYPE 以及保证 DOCTYPE 在 HTML 文档中绝对开头的位置则是使 DOCTYPE 发挥其正确作用的关键。

测试环境

操作系统版本:Windows 7 Ultimate build 7600
浏览器版本:IE6
IE7
IE8
IE9
Firefox 4.0.1
Chrome 12.0.742.100
Safari 5.0.5
Opera 11.11
测试页面:
本文更新时间:2011-06-17

关键字

浏览器 兼容性 渲染模式 标准模式 混杂模式 DOCTYPE DTD

以上就是DOCTYPE与浏览器渲染介绍的详细内容,更多请关注 第一PHP社区 其它相关文章!


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
author-avatar
手机用户2602906647
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有