一、前言
原本备份: http://www.cnblogs.com/fsjohnhuang/p/3830623.html
由于本人英语能力有限,译本内容难免有误,望各位指正!
本译文不含附录部分,请知悉。
二、译文内容
为了让用户正常访问遵循Web标准的网站和90年代后期的非标准网站,当前的浏览器都内置了多种引擎模式。本文将解释这些模式和它们触发的原理。
本文概要(没耐性的同学看完这个就可以闪了!)
本文结论:以<!DOCTYPE html>作为你们的HTML文档(http头的mime为text/http的文档)的首行。
如果你们希望禁止用户在使用IE8、9、10浏览你的网站时,不会因点击地址栏旁的兼容性按钮而导致网站以IE7的文档模式被解析、渲染,那么就在HTTP头那加上X-UA-Compatible: IE=Edage,或在<head></head>间加句<meta http-equiv="X-UA-Compatible" content="IE=Edge">吧。其实IE一般都会选择合理的文档模式,所以没什么必要加上述IE独有的魔咒。
本文的上下文
本篇覆盖Firefox、其他基于Gecko内核的浏览器、Safari、Chrome、其他基于Webkit内核的浏览器、Opera、Konqueror、IE 4 Mac,IE 4 Windows(包含4 WP)和其他IE内核的浏览器的模式转换。并使用知名浏览器来代表各款内核描述模式转换。
本文重点讲解模式选择的机制而不是各种模式对应的
行为特征。目的是让大家理解如何避免陈旧的模式,当然也不是旨在促进大家采用更良好的模式了。
各种模式
text/html 内容的模式
一般来讲doctype嗅探将影响text/html内容的模式。IE8+影响模式的要求就更加复杂,其中包含网站是否为内网网站,该网站有没有添加到兼容性视图列表当中。倘若IE6、7中安装了Google Chrome Frame插件,那么就不仅doctype嗅探会影响text/html内容的模式了。(Google Chrome Frame其实就在IE6、7、8、9下使用Webkit作内核的插件)
怪异模式
怪异模式是浏览器为了正确呈现90年代后期制作的网页,从而违反当前Web规范的模式。以前,各浏览器的怪异模式各不相同。IE6789的怪异模式其实就是IE5.5的文档模式,而其他浏览器的怪异模式就稍微与近标准模式有偏差而已。但IE10开始,其怪异模式不再仿照IE5.5的文档模式了,而是和其他浏览器的怪异模式相近了。
如果你正在开发一个新网站,千万不要用怪异模式,用标准模式吧朋友。
标准模式
标准模式下,浏览器尝试对网站提供HTML规范处理外,还提供浏览器独有的各种特性。
由于各浏览器对HTML规范实现的不同,所以各浏览器的标准模式不尽相同。
在HTML specification中标准模式被称作“非怪异模式”。
准标准模式
Firefox、Safari、Chrome、Opera(从7.5开始)、IE8910,有有“准标准模式”,其不按CSS2标准而实现了vertical sizing of table cells(求高手解答,这是啥啊?)。Mac IE5,Windows IE67,Opera7.5前的版本和Konquer均没有准标准模式,因为它们在各自的标准模式中实现了vertical sizing of table cells。实际上,它们的标准模式更接近于近标准模式而不是现在浏览器的标准模式。
回顾历史我们会发现,在不区分“标准模式”和“近标准模式”,默认使用“准标准模式”的行为特征,并使用“标准模式”的CSS特征会让Web更美好。不过我们依然应优先使用“标准模式”。
在HTML specification中准标准模式被称为“受限的怪异模式”。
application/xhtml+xml内容的模式(XML模式)
Firefox,Safari,Chrome,Opera 和 IE9,HTTP头的Content-Type为application/xhtml+xml会触发XML模式。当处理XML模式时,上述浏览器会结合自身浏览器所提供的特征行为并符合标准规范来解析、处理XML文档。
· 除了IE5外,IE678是不支持application/xhtml+xml的。
在基于Webkit内核的Nokia S60浏览器下,由于考虑到兼容性问题,即使HTTP头的Content-Type为application/xhtml+xml是不会触发XML模式的,而是采用移动终端范围内的非规范内容处理XML(由于历史遗留的移动浏览器没有真实的XML解析器,因此XML会被标识为非规范话内容)。
我没有在塞班自带的浏览器上测试过,也没有在Konqueror上作充分地测试,所以不敢保证其准确的行为模式。
IE特有的模式
以下的模式是IE独有的,并不符合HTML5规范且其他浏览器均没有实现的。通过在HTTP头或meta元素设置X-UA-Compatible来触发。
IE5怪异模式
除了和其他浏览器相近的怪异模式外,IE10还提供了一个“IE5怪异模式”,其实就是IE6789的怪异模式而已(IE5.5的文档模式)。
IE7标准模式
IE8910提供该模式用于模拟IE7的标准模式。
IE8标准模式
IE910提供该模式用于模拟IE8的标准模式。
IE8准标准模式
IE910提供该模式用于模拟IE8的准标准模式,但在开发者工具中,该模式和IE8标准模式是合并在一起的(译者语:那怎么启用准标准模式呢??)
IE9标准模式
IE10提供该模式用于模拟IE9的标准模式。
IE9准标准模式
IE10提供该模式用于模拟IE9的准标准模式,但在开发者工具中,该模式和IE9标准模式是合并在一起的(译者语:那怎么启用准标准模式呢??)
IE9 XML模式
IE10提供该模式用于模拟IE9的XML模式,但在开发者工具中,该模式和IE9标准模式是合并在一起的。
其实并没有任何价值去模拟这些臭名昭著的IE版本。例如,在IE10下使用IE9模式处理@font-face类 EOT 字体时和真实的IE9是不同的,前者由于IE10开始支持CSS 2D转换,因此CSS属性就不用带-ms-前缀,而后者就需要-ms-前缀了。倘若你遵守本文提供的建议,那么你就不用理会这些模式了,因为这些不完美的模拟器并不会影响到你和你的产品。然而,更快捷的方式是在虚拟机上使用各款真实的旧版IE测试你的网站,而不是使用模拟器。
WP8的IE10同样拥有上述的所有模式,当然也是不完美的模拟器而已。
Google Chrome Frame下的IE特有的模式
在IE6789下安装了Google Chrome Framke插件,那么就会有一下的IE特有的模式(IE10开始没有这些模式了)
Chrome 怪异模式
就是Chrome下的怪异模式(不是IE5.5的文档模式)
Chrome 标准模式
就是Chrome下的标准模式
Chrome 准标准模式
就是Chrome下的准标准模式
非Web的模式
某些引擎拥有一些与Web无关的模式。列举这些模式仅为本文内容的完整性而已,将不作深入。Opera有WML 2.0模式,在Mac OS X 10.5下的Webkit有个专为历史遗留的Dashboard组件而设的模式。
模式的作用
布局
除了IE,text/html的模式主要影响CSS布局和样式系统。例如,table中没有样式继承是怪异模式的特性。在IE6789和Opera下,怪异模式就是IE5.5的文档模式。本文无法一一列举怪异模式下的所有布局特征。大家可以参考Mozllia's documentation和Quirks Mode specification。
在准标准模式下,单元格内仅含图片时,单元格的高度与标准模式的计算是不同的。
在XML模式下,选择器有不同的大小写行为。例如,有些对于HTML的body元素的规则在那些没有实现CSS新规范的旧浏览器中将失效。
解析
在怪异模式下,会导致符合W3C标准的页面的HTML和CSS解析出错。这些错误伴随着怪异模式的布局出现。注意,我们提及的怪异模式和标准模式的对决,主要针对CSS布局和CSS解析,而不是HTML解析。浏览器中有一个遵循HTML5规范的HTML解析器,更多请浏览 exactly one HTML parsing quirk。
有些朋友误认为标准模式就是doctype上的“strict parsing mode”,其实两者没啥关系。(2000年夏季时,网景6推出与"strict parsing mode"关联的模式,就是"Strict DTD",但因与现有网站均不兼容导致最终被废除了)
另一个常见的误解是关于XHTML的解析的。常常认为使用XHTML的doctype时,会触发浏览器使用不同的DOM解析器。但由于HTTP头的Content-Type依然是text/html,所以还是使用相同的HTML解析器。浏览器厂商意识到XHTML只是带额外限制的HTML而已,所以仅仅当HTTP头的Content-Type为application/xhtml+xml或application/xml时才触发XML模式,并采用XML解析器替代HTML解析器。
脚本
虽然怪异模式主要影响CSS,但也会影响到脚本。在Firefox14前的标准和准表尊模式下,HTML的id属性都不会自动在全局范围内创建dom对象的引用;仅当处于怪异模式下,document.all才部分生效。(译者语:现在很多浏览器都实现了document.all了,因为好用嘛!)当你通过模拟器在个版本的IE上测试时,模式对脚本的影响会明显。
在XML模式下,部分DOM APIs的行为会与其他三种模式的很不同,这是由于XML和HTML定义的DOM API本来就不兼容而导致。悲催了吧!
Doctype嗅探(就是Doctype切换)
浏览器通过doctype嗅探来决定text/html内容的使用哪种引擎模式。也就是说模式是取决于<!DOCTYPE html>这句的。
doctype是SGML的语法(HTML5前的标记框架,仅用于声明HTML的版本信息,而不能用于区分是SGML还是XML文档)。
但无论是HTML4.01还是ISO 8879(SGML)都没有标明可以通过doctype来切换浏览器的引擎模式。而设计通过doctype来切换浏览器的引擎模式,是由于大部分使用怪异模式的网站均没有写<!DOCTYPE html>或指向旧的DTD,所以就采用doctype来做切换开关了。而在HTML5规范设计的时候发现doctype的最实际用途就是用来切换模式而已,所以最后得到最简的doctype "<!DOCTYPE html>"
过去的doctype格式:<!DOCTYPE 根节点标签名 PUBLIC "公共标识符" "系统标识符">
教你选择doctype
下面是简单的教程,让你为你的新网站(text/html)选择合适的doctype。
1. 标准模式,可验证最新特性
<!DOCTYPE html>
建议使用该doctype,它会验证最新的特性(如,<video>、<canvas>等)
2. 标准模式,不验证最新特性,是历史遗留的严格模式
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/html4/strict.dtd">
3. 准标准模式,不验证最新特性,是历史遗留的松散模式
4. 怪异模式,没有doctype
最好不要这样做,否则你会后悔的。
加入因客户需求导致你不得不考虑怪异模式,那请你使用IE的条件注释而不是省去doctype吧。
我不建议使用XHTML的doctype,以为将XHTML作为text/html处理是有害的。如果你使用XHTML作为doctype,在IE6下会切换为怪异模式。
对application/xhtml+xml
没有必要使用doctype。没有doctype时,网页就不一定需要严格遵循XHTML1.0规范,但也没必要遵守。
IE8、9、10的复杂问题
从IE8开始可通过meta元素来切换模式。
IE8有4种模式:IE5.5怪异模式,IE7标准模式,IE8准标准模式和IE8标准模式;IE9有7种模式:IE5.5怪异模式,IE7标准模式,IE8准标准模式,IE8标准模式,IE9准标准模式,IE9标准模式和IE9XML模式;IE10有11中模式,IE5.5怪异模式,IE7标准模式,IE8准标准模式,IE8标准模式,IE9准标准模式,IE9标准模式,IE9XML模式,IE5.5怪异模式,IE7标准模式,IE8准标准模式,IE8标准模式,IE10准标准模式,IE10标准模式和IE10XML模式。
而使用哪种模式依赖于以下设置项:
1. doctype
2. meta元素
3. HTTP头设置
4. 周期性从微软下载的数据
5. 用户或内网管理员的内网区域设置
6. 父框架的模式(应用内嵌浏览器的模式取决于应用本身)
幸运的是,IE8、9在符合下列条件时会行为模式和其他浏览器大概相似,而IE10就精准相似了。
1. 没有将X-UA-Compatible加入到HTTP头中;
2. 没有将X-UA-Compatible加入到meta中;
3. 微软没有将该域名加入到它的黑名单中;
4. 内网管理员没有将该网站(域名或IP)加入到黑名单中;
5. 用户没有点击兼容性视图按钮(仅HTTP或HTTPS协议时才会自动出现),且没有将该网站(域名或IP)加入到本地的和黑名单中;
6. 网站不是内网区域网站;
7. 用户没有选择使用IE7模式来显示所有网站;
8. 网页的父框架没有使用兼容性模式。
在IE8、9中使用兼容性视图,实际上就是使用模拟IE7模式。
不幸的是,如果在IE8、9中没有X-UA-Compatible的HTTP头或meta元素时,即使你添加了合适的doctype,浏览器依然允许用户自行回退到模拟IE7模式中。更糟的是,内网管理员也可以这样做。
鉴于上述情况,doctype已经不足以确保你的文档模式了,于是你需求求助于X-UA-Compatible,无论是在HTTP头还是meta元素。
下面是简单的教程,告诉在已经通过doctype触发标准模式的情况下,如何选择X-UA-Compatible的HTTP头或meta元素了。
1. 关注点:你的网站不在微软的黑名单中,而且你更关心避免依赖浏览器各版本特有的特征,而不是用户使用模拟IE7模式解析网站。
建议:无需添加X-UA-Compatible了。
2. 关注点:你的网站在微软的黑名单中,而且你不希望用户使用模拟IE7模式解析网站。
建议:添加<meta http-equiv="X-UA-Compatible" content="IE=Edge">或HTTP头上添加X-UA-Compatible: IE=Edge
3. 关注点:在IE8、9下使用模拟IE7标准模式
建议:添加<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">或HTTP头上添加X-UA-Compatible: IE=EmulateIE7。然后不要依赖非IE7的行为特征
4. 关注点:在IE9下使用模拟IE8标准模式
建议:添加<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">或HTTP头上添加X-UA-Compatible: IE=EmulateIE8。然后不要依赖非IE8的行为特征
5. 关注点:在IE10下使用模拟IE9标准模式
建议:添加<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">或HTTP头上添加X-UA-Compatible: IE=EmulateIE9。然后不要依赖非IE9的行为特征
Google Chrome Frame的复杂问题
Google Chrome Frame是IE6789下让IE使用Webkit内核的浏览器插件。安装后,IE默认还是用回Trident内核,但可以通过X-UA-Compatible切换为Webkit内核。
X-UA-Compatible: chrome=1,会触发切换到Webkit内核;X-UA-Compatible: chrome=IE6,表示IE6时触发切换到Webkit内核;X-UA-Compatible: chrome=IE7,表示IE6和IE7时触发切换到Webkit内核。
Chrome Frame的X-UA-Compatible指令可以和IE本身的指令一起使用,如<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=IE8">
一旦切换成Webkit内核,那么就使用Google Chrome Frame下的IE特有的模式。
建议不要使用Chrome Frame:
1. 由于该插件没有得到IE在可访问性上的支持,所以通过屏幕阅读器和Windows语言识别器是无法访问该插件的内容的;
2. 需要客户端安装该插件。