一、前言
原本备份: 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. 准标准模式,不验证最新特性,是历史遗留的松散模式
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/html4/loose.dtd">
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. 需要客户端安装该插件。