北漂IT民工 的博客

浏览器兼容性问题的探讨

浏览器兼容性的问题是一个相对比较复杂的问题,也是困扰了很多开发人员的常见问题。
今天我准备从原理的角度分析一下,浏览器的兼容性问题到底有那些,应该如何解决。
但是我不会特别具体的讲解浏览器的具体兼容性问题,因为这个部分的内容过于多了,而且很多已经过时了。
我这里要讲的内容,大概是既使10年后也是仍可以作为参考的内容。
因为兼容性的问题是一个比较常态的话题,不会随着浏览器的发展而突然消失。

浏览器兼容性问题产生的原因主要有以下几个:

  1. 标准的从无到有与标准的版本升级
  2. 标准与实现的差异
  3. 向下兼容所带来的负担
  4. 软件bug
  5. 标准往往是滞后的

标准的从无到有与标准的版本升级

互联网的发展与任何其它事物的发展是一样的。一开始的混乱到现在的相对规范都是历经长时间的考验与认识的提升所得到的。
一开始HTML的标准与现在的HTML标准已经发生了很大的变化。
从一开始的HTML到现在的HTML5,标准已经提升了很多
每一次的提升,都或者多或者少的影响着的网页的开发原则与展现原则。
因些每一次变化都是对之前的一种或多或少的否定
而这些否定则是来源于开发实践或者浏览器厂政治斗争的结果。
所以标准仍会不断的向进步与发展,并且不断的制造兼容的问题,
因为标准都是人的认识的体现,人的认识不断的变化,标准必然不断的变化
所以不能盲目的迷信标准,标准不见得就是正确的认识。

标准与实现的差异

标准是一个规范,而最终用户所接触到的浏览器是一个实现。标准与实现总是会存在差异的。有时候这种差异特别大。这个差异显著的发生在ie的旧版本上。
而最知名的就是盒模型(box model)与事件模型在ie上与标准存在明显的差异。
盒模型造成的兼容问题,在早期是非常显著的,随着IE对标准的支持越来越好,标准与实现的差异问题有所减少。
如果从实践开发来说,显然ie的盒模型比w3c的盒模型要更符合大多数人的理解。所以css3之后,盒模型也是一个可选的参数了。

向下兼容所带来的负担

大概这是带来问题最多的地方了,因为这也是产生兼容性问题的根本原因所在。
因为要向下兼容,所以才会存在兼容性问题。
如果不需要兼容,那么兼容性的问题就不存在了。

为了解决兼容性的问题,浏览器创建了各种模式用于解释不同的标准的网页。
为了方便了解网页的版本,浏览器厂商又发明了DOCTYPE用于测试网页所使用的HTML的版本。
这样一来导致了网页的HTML版本有很多种,解释的方式也有很多种。
有些浏览器还能针对不同的浏览器版本再衍生出来多个版本,
为了保证浏览器的展示正确,会不断的加入渲染模式,导致一个浏览器上竟然存在将近10种的模式,
这只能说是网页开发的恶梦。
最典型的就是ie浏览器:
在ie10里,会包括ie9,ie8,ie7的标准模式与部分的几乎标准模式,还会包括ie5怪异模式。

对于大部分的浏览器来说,一般会包含三种渲染模式:

  1. 标准模式(standard mode)
    按w3c标准进行解析

  2. 几乎模型模式(almost standard mode)
    除了在下面的方面表示与标准模式一样:
    “the height calculations for line boxes and some of the inline elements in them.”
    也就是说在线性块高度的计算时,可能如果有一些inline的元素在的话,可能就会进入几乎标准模式。
    但是这种几平标准模式也不是随便进的,具体的如何进,跟你的DTD版本与浏览器有关。
    关于详细的为什么要进入几乎标准模式,参考quirksmode
    关于什么是几乎标准模式,如何进入,参考Gecko’s Almost Standards Mode

  3. 怪异模式(quirks mode)
    实际上是早期的Web页面解释规则,现在的页面应该是避免进入这一个状态。
    同时不同的浏览器的怪异模型的解释方式并不相同。
    当你的页面表现跟你的预期差别很大时,你要检查一下你所开发的网页是不是进入了这种模型。

    这种根据DOCTYPE切换模式的方式被叫做DOCTYPE switching或者DOCTYPE sniffing。
    由于之前的DOCTYPE种类繁多(XML化的副作用),到了HTML5之后规定,只需要

1
<!DOCTYPE html>

就可以正常的触发标准模式了,并且对于大部分的浏览器都是适用的。
这种表达方式一定程度上说明了HTML的XML化的失败。

关于这些模型如何启动的内容可以参考这篇文章, Activating Browser Modes with Doctype

对于当前的我们来说,基本上已经不需要进入除标准模式以外的模式了。
所以将其它的模式当成是历史,了解一下就差不多了。

软件bug

任何软件都或多或少会存在一些缺陷,通常我们称之为bug。
浏览器也不例外,所以在平时开发时,任何前端开发工程师都会或多或少碰到浏览器的bug。
浏览器的bug通常是跟浏览器的版本有关,
现在的浏览器由于更新很及时,所以现代的浏览器的bug修复通常都会非常的及时。
所以bug的修复慢慢的会是兼容性问题上一个相对比较小的问题。
bug的修复需要坚持的原则就是要从原理上去修复,而不是从展现上去修复。
因为对于某些bug的修复的技术是很多样的,采用不同的CSS也许就可以完成,所以修复最好是通过避免使用带bug的结构或者属性来规避。

标准往往是滞后的

通常由于业务的需要,Web技术不断的向前推动,但是由于标准往往是落后于现实的,所以这种情况下,不兼容是必然会产生的。
典型的例子就是ajax技术最初是由微软发起的,在IE平台下是一个ActiveX对象。而W3C由于定义规范与多平台的原因,是不可能定义成为ActiveX的。
所以当W3C标准支持ajax时,它的名称就被定义成为了XMLHttpRequest。
这些当标准出来后,新的代码就需要去兼容标准的与非标准的代码。

总结

  1. 兼容性问题是一个永存的问题
    不会随着版本的升级而消失,但是我们上面提到的很多内容会随着版本的升级与时间的推移消失。象几乎标准模式,怪异模式,DTD,旧版本上的bug,因为滞后标准所带来的功能缺失。
    但是对于浏览器的功能,展示不统一,新版的浏览器bug,新标准的不一致等问题是永远会存在的。
    所以在浏览器问题上没有一个一劳永逸的解决办法,只是有些原则或者理解是可以保留下来的。

  2. 标准模式下,一样存在着兼容性的问题
    所以对于大多数网页开发者来说,最重要的要理解的一点是,即使你是标准模式,你也是需要解决浏览器兼容性问题的。浏览器标准模式是现代网页开发技术的基础。没有了标准模式,开发网页的技术基础就没有了。

  3. 标准并不见得都是好的
    网页标准的制定者是人,人就难免是主观的,会出错的。所以标准只是标准,并不能表示它有多好,多正确。标准往往有时候是违反人性或者习惯的。
    这种标准最终往往是随着时间的流逝而被抛弃。比如XHTML,去除a标签的href属性。

上述内容,我们简单的回顾了网页开发上面的兼容性问题,目标在于帮助开发者理解这些兼容性问题产生的原因,并以此找到解决问题的办法。
(由于水平所限,以上内容出错在所难免,欢迎批评指正)