过度追求浏览器兼容其实就是拿不同浏览器开发者的个性或Bug惩罚自己!
前言
Web Developers 往往会因为自己的作品无法“完美兼容”多个浏览器而苦恼不已,然后责怪自己水平不够或者MSIE把你惯坏毒害了以至于无法写出“标准的HTML+CSS+JS”!
但事实上,很多所谓的兼容性问题未必都是 Web Developer 自己造成的,也会有浏览器本身的问题!毕竟浏览器开发商也是人,也会犯错误,他们的软件同样会有Bug,唯一不同的是,他们所犯的错误往往会“惩罚”和困扰数以千万计的下游Web开发者!
当然了,话说回来,就算浏览器自己犯了错误,也不能作为 Web Developer 不去考虑兼容性的借口,毕竟你不能告诉网站用户“您眼前的页面显示不完美现象将会在下一版本的Firefox/Opera/Chrome中得到解决,请耐心等待新版本的发布……”,开个玩笑:)
因此研究不同浏览器各自的特点及其所犯错误的表现总是有必要的。
下面说说我怎么会想到研究这个问题的。
目前正在开发的网站产品对用户体验和交互水准要求比较高,网站会用到许多有特色的自定义控件,然后在我对这些控件进行封装(采用 jQuery plugin 的形式)的时候遇到了一系列浏览器兼容方面的问题。
事实上这已经不是单纯的浏览器兼容性问题了,而是浏览器自身对同样的Html+CSS代码渲染时出现了问题(问题看似小问题,但是对实际应用中的用户界面破坏很严重)。具体说就是:
当用户进行页面缩放浏览的时候,即便同一个浏览器软件,在不同缩放比例下渲染出的效果也是不一致的,会出现各种各样的毛病,造成讨厌的视觉效果破坏。
然后为了彻底解决这种类型的问题及其造成的破坏,我不得不从根本上去找原因,找解决方案,于是就有了这篇文章。
一、遇到问题的jQuery插件
上面提到我在开发时遇到问题的 jQuery plugin 之一是一个“庸俗的” Button ,说它庸俗是因为这样的插件目前在 jQuery 的世界里至少已经有数以万计了,但是我却还是没能找到一个真正完美的,或者说能让我满意的,也许骨子里的真正原因是人都更希望使用自己可控制的东西吧。
简单介绍一下这个 Button plugin :为了支持丰富的视觉效果和更容易在页面中进行控制,我采用Div来模拟一个“四态(normal,hover,pressdown,disabled)按钮”,你只需要通过改变CSS,就可以创建出简洁的文本按钮,通过CSS结合使用背景图片更能够模拟出各种独具特色的按钮形态,关于它,后面我会另开文章介绍,这里就不罗嗦了。
严格来说,一个具有通用性的按钮应当采用九宫格的“四角固定,中间区域自动拉伸”模式来进行渲染,这样才能使得按钮可以随意控制高度和宽度,并且在不同尺寸下都能够表现完美,但是 Web 开发有其独特性,我们这个按钮只需要能够满足自动延展宽度就行,故而采用“左中右三段渲染”的方式进行开发。
因此,在这里您只需要记住我们是用3个Div来分别模拟按钮的左中右样式即可。
作为一个按钮,当然不仅仅是模拟一个 Button look Face 那么简单,它还要能够实现形态变化,响应鼠标事件乃至键盘动作,以此来宣示自己的按钮身份并实现相应的功能。然而这些并不是本文的讲述重点,本文只关注外观模拟的部分,完整的 Button Plugin 开发文章,会在今后放出。
二、本文所讨论问题的现实意义
肯定有人会觉得,你非要用 Div 去模拟一个 Button 效果,这分明就是自寻烦恼,你这个例子根本不具有代表性,因此也说明不了什么问题。
真的是这样吗?未必见得吧!就算用 Div 模拟 Button 这件事儿本身是我自己闲的蛋疼,可是我总归是在使用 Html+CSS 去实现一个视觉效果,这一点你无法否认吧。而 CSS 对于网页来讲,其作用无非就是帮助页面排版布局,与Html一起为用户展现出友好优雅的视觉效果而已。那么既然在我实现这个视觉效果的时候遇到了问题,别人在实现其他视觉效果的时候同样也会存在问题,我这里是模拟按钮出问题,别人那里就有可能是页面模块对齐出现错位,影响会更大!这就是本文的现实意义所在!
当然了,也许还有善于抓漏洞的朋友会说“你这个所谓的‘不同缩放比例下的渲染效果差异’只有在用户不断改变网页大小的时候才会出现,事实上又会有多少用户会像你一样闲的蛋疼,逮着一个网页缩来放去呢,因此这点小差别一般用户根本就不会有机会感知的到,你这么斤斤计较又是何苦呢?”
聪明!精彩!貌似合情合理且又丝丝入扣!
然而我的答案是这样的:
1、你所描述的情况基本属实,但是这能够成为浏览器渲染页面可以不严谨的借口吗?难道某些浏览器一方面宣称支持这标准那规范,对“不标准”的微软大加鞭挞,另一方面却又对自己要求降低吗?
我就想问一句:凭什么我写的无错的、且“标准的” CSS 和 HTML ,你们在不同缩放比例下给我渲染出来却不一样?
(抱歉,吐槽到此结束)
2、为了避免有人说我只会讲大道理,给出两个更直观的理由:
- A、现在 iPhone 手机和 Android 智能手机大行其道,对几乎所有网站来讲,使用这类设备上网访问的用户比例已经在不断提升,而且还将持续大幅提升!而目前为止并非所有网站都有能力为用户提供一个移动终端的专用版本(别跟我提 Wap ,玩这种手机的人绝对不会对 Wap 网站感兴趣,因为 Wap 体现不出他们手机的优越性),所以绝大多数这类用户都会用他们的手机浏览器( Safari Mobile 或者 Android 自带的 Webkit 内核的浏览器)来直接访问你的Web网站,而无论 iPhone 还是 Android 上的手机浏览器都有自动缩放页面的功能(当然这是因为手机的屏幕分辨率小),此时缩放后的页面渲染效果就显得至关重要了!比如你网页上一个140像素宽的按钮,经过 iPhone 的缩小适应屏幕宽度之后就只有一点点了,而你想准确的点击操作它的话一般都会进行放大操作,而这时,按钮撕裂了……
- B、台式电脑用户都在大幅提高自己的配置,显示器21寸以下你都不好意思跟人打招呼,23寸才算马马虎虎,分辨率自然是1920*1080了,然而在这种分辨率下看网页的默认字体会有多吃力你想过么?怎么办?放大网页呗,多简单啊,按住Ctrl+鼠标滚轮一滚,哇,放大的文字好牛逼!等等……什么?按钮撕裂了?太尼玛煞风景了!
好了,看完这两条依然认为这个问题没有意义的筒子们,您可以出门右拐了,这篇文章对您没啥用,真的……
三、浏览器测试环境
浏览器兼容性测试是个很讨厌的工作,首先环境搭建就很烦:
我在自己的 Win2003 上面安装了 IE8,Chrome11,Firefox5,Opera11,Safari5,又在虚拟机上安装了 IE6,IE7,然后还可以使用别人 Win7 上的 IE9 ,这样就基本覆盖了 Windows 上面的常用浏览器,也将作为我的测试环境。
对于 Linux 来说,常用浏览器无非也是 Firefox,Opera,Webkit 这三个内核,他们的表现与各自的 Windows 版本相比并不会有本质不同。苹果的 Mac OS 所使用的 Safari 与 Windows 下的 Safari 一样大同小异。因此我就没有单独安装这两个系统进行测试,以后有机会,这一课我会补上的。
当然了,现在这个时代,要测试浏览器兼容性,你还少不了 iPhone ,运行在 iPhone 上面的 Safari Mobile 目前可是相当大的一个访问群体哦,另外还有我的 Android ,除了其自带一个 Google 自己开发的以 Webkit 为内核的浏览器,还有 Firefox 和 Opera 分别为 Android 平台开发了响应版本的浏览器,这次把它们一并纳入测试范围!唯一有点遗憾的是微软的 WP7 ,暂时没有机器可以进行测试,后面我会附上页面源码,希望有条件的筒子帮我测试一下。
总结一下,现在我们有了
IE6/IE7/IE8/IE9/Firefox5/Opera11/Safari5/Chrome11/Safari Mobile/Firefox Mobile/Opera Mobile/Chrome Mobile
作为测试环境!
四、发现和解决问题的详细过程
1、首先用4个Div和纯CSS来模拟一个简单按钮的外形
由于本文旨在分析浏览器页面渲染的差别,故而按钮的状态变化、事件响应等在这里不做实现,这个页面分别采用了float和absolute两种布局对按钮进行了模拟,先看代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Browser Tester</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <style type="text/css"> *{ margin: 0px; padding: 0px; border: none; } body{ background-color: Purple; padding: 20px; } /*按钮自身的容器*/ .Container{ height: 40px; width: 200px; position: relative; } /*按钮左中右容器基本样式设定*/ .Left{ width: 10px; height: 100%; background-color: Yellow; } .Center{ width: 180px; height: 100%; background-color: Orange; color: White; text-align: Center; font-size: 14px; line-height: 40px; } .Right{ width: 10px; height: 100%; background-color: Yellow; } </style> </head> <body> <div id="floatContainer" class="Container"> <div class="Left" style="float: left;"></div> <div class="Center" style="float: left;">Float方式模拟的按钮</div> <div class="Right" style="float: right;"></div> </div> <br /> <div id="absoluteContainer" class="Container"> <div class="Left" style="position:absolute;left: 0px;"></div> <div class="Right" style="position:absolute;left: 190px;"></div> <div class="Center" style="position:absolute;left: 10px;">Absolute方式模拟的按钮</div> </div> </body> </html>
代码比较简单,注意这里把用来模拟按钮的div基本样式都放在了文档头部的<style>块里面,而具体到两种不同布局方式的差别部分,为了直观起见,我直接写在了标签的style属性里面。下面看效果:
| IE6 |  |
| IE7 |  |
| IE8 |  |
| IE9 |  |
| Firefox |  |
| Opera |  |
| Chrome |  |
| Safari | |
大家看到了,在各浏览器标准显示比例下解析出来的效果接近一致,非常"完美"!等等,这就行了么?显然不是的,否则就不会有这篇文章存在的价值了。
另外,其实仔细看的话,不同浏览器对页面渲染的区别已经初露端倪,比如:
A、不同浏览器对默认字体的选择是不一样的,有的是宋体,有的是雅黑……好吧好吧,这个可以理解,算我吹毛求疵,我该在CSS指定默认字体的……
B、对line-height的解析和渲染,各浏览器并不一致,有兴趣的可以自己截图对比一下,尤其是IE系列,相比其他浏览器总会有向上偏移,除IE9之外的其他IE版本,通常宋体会上偏2个像素,雅黑会上偏1个像素(所以你知道的,为了美观起见,尽量用雅黑吧)
C、对于<br/>的解析,高度不尽相同,当然这个并不十分影响视觉效果,但是依然体现了各浏览器开发商的“不负责任”,你们整天骂人家微软不遵守标准,你们倒是好好遵守啊。
2、对模拟出的简单按钮效果在不同浏览器下分别进行缩放测试
| IE6 | IE6无整页缩放功能,测试忽略 |
| IE7 | 测试结论: IE7提供了最小10%,最大无限比例的缩放功能。 页面在小于(含)50%比例下显示的时候<br />效果消失,两个按钮粘连在一起; 在最小10%的显示比例下文字渲染还超出了按钮边界; 在放大比例的时候对<br />的渲染处理不好,高倍显示下这个换行非常夸张; 除了上述三个小问题外,其他比例均可以算作显示良好。 我的打分:70 |
| IE8 |  测试结论:IE8同样提供最小10%最大无限的整页缩放功能 ,即便在最小的10%的比例下,两个按钮依然没有出现粘连; 不过小问题依然存在,那就是在10%比例下,文字出现了换行,虽然无实际意义,也算一点小遗憾吧; 除此之外,可以看到IE8对放大时两个div之间<br />的间隙做了更加人性化的处理,不像IE7那么生硬了。 我的打分:85 |
| IE9 |  测试结论:IE9提供了最小10%最大无限的整页缩放功能,而且表现完美! 不知道微软有没有刻意处理这些,但是之前IE7和IE8出现的小问题全部消失了 ! 我的打分:98(留点改进空间给微软吧) |
| Firefox |  测试结论:Firefox提供了在正常显示的基础上缩小5级放大8级的限制策略,非常聪明和实用; 跟IE9相比,除了缩放倍数受限一点之外,在渲染效果上不相上下,很赞! 我的打分:95(缩放倍数受限扣3分) |
| Opera |  测试结论:Opera提供了最小20%最大无限的整页缩放能力且在不同缩放倍数上的渲染效果均很优秀; 其渲染质量与IE9和Firefox不相上下。 我的打分:98(与IE9打平) |
| Chrome | 测试结果: Chrome提供了最小50%,最大300%的固定级别缩放功能,总共12个缩放级别; 在这12个缩放级别里面总共出现了如下多的问题,让我比较失望: a、50%和57%两个比例下, 文字错行; b、57%,69%,144%,207%四个比例下,Float定位方式Center和Right之间出现了 1像素的缝隙; c、而在248%和298%两个比例下,Float定位方式出现了2像素的缝隙! 不仅如此,连Absolute方式也出现了1像素缝隙! 我的打分:50 |
| Safari |  测试结果:其实不难想象,同为Webkit内核的Safari在处理上不会比Chrome好到哪里去,结果证实了这一点: 不过Safari毕竟聪明,他把缩放限制为10个级别,甚至你连缩放比例都看不到,囧! 不过借此倒是隐藏了文字折行的bug,只剩下裂缝问题了: a 、第1,第2,第6,第8级别Float方式出现1像素裂缝; b 、第9,第10级别,Float方式的裂缝扩大到2像素,而absolute方式也出现了1像素裂缝! 我的打分:55 |
测试小结:
A、在浏览器渲染能力方面,其实微软一直在进步,他追求的高容错能力的的确确在为用户体验考虑,而这却成了别人攻击他“不标准”的口实!
B、Firefox和Opera这两个有着深厚底蕴的家伙的确手里有真功夫,然而这还只是个开始,更多测试在后边。
C、一直为人所推崇的Webkit其实远没有那么完美,只不过人家抓住了“快”这一噱头和卖点!再加上无论Apple还是Google都是善于宣传推广灌输的高手,所以……
D、从CSS使用角度来讲,Float的布局方式更容易出偏差!如果您为了图文布局方便,尽管大胆的Float就行了,可如果是想实现某些漂亮的视觉效果,那么请三思。
3、纯CSS的渲染已经出现问题,那么如果换成图片模拟按钮呢?
前面用纯CSS模拟的按钮出问题了,很不幸!那么如果我用图片来进行模拟呢?会好一点?或者更糟?让测试结果来证明吧!
下面我写一个新的页面,使用图片来模拟按钮的Normal态(其他三态原理相同),先看看这个背景图片

这是一个png格式的图片,宽6像素,高度105像素,背景透明,按钮实体高度为32px,我在设计的时候是按照35像素做的,原因后面会有解释。
然后修改CSS和网页代码,使之能够模拟一个图片按钮的左中右三段(之所以采用三段的方式来模拟是因为我们封装的按钮是希望宽度不受限制的,因此固定宽度背景图片搞不定),下面是全部代码(听取批评,给body设置了默认字体为雅黑):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Browser Tester</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <style type="text/css"> *{ margin: 0px; padding: 0px; border: none; } body{ background-color: Purple; padding: 20px; font-family: "微软雅黑", "宋体"; } /*按钮自身的容器*/ .Container{ height: 32px; width: 200px; position: relative; } /*按钮左中右容器基本样式设定*/ .Left, .Center, .Right{ background-image: url('btn_bg_noShadow.png'); } .Left{ width: 6px; height: 100%; background-repeat: no-repeat; background-position: 0px 0px; } .Center{ width: 188px; height: 100%; background-repeat: repeat-x; color: White; text-align: Center; font-size: 14px; line-height: 32px; background-position: 0px -35px; } .Right{ width: 6px; height: 100%; background-repeat: no-repeat; background-position: 0px -70px; } </style> </head> <body> <div id="floatContainer" class="Container"> <div class="Left" style="float: left;"></div> <div class="Center" style="float: left;">Float方式模拟的按钮</div> <div class="Right" style="float: right;"></div> </div> <br /> <div id="absoluteContainer" class="Container"> <div class="Left" style="position:absolute;left: 0px;"></div> <div class="Right" style="position:absolute;left: 194px;"></div> <div class="Center" style="position:absolute;left: 6px;">Absolute方式模拟的按钮</div> </div> </body> </html>
正常比例状态下的按钮效果图我就不一一截图贴出来了,除了IE6不支持透明png图片有点丑之外都很完美:

说到IE6,我以后开发的Web应用几乎都不再考虑它了,从现在的形势来看,IE6被放弃将是很短时间内的事情,我乐意提前一步。
下面要做的是我不怎么喜欢的,给浏览器挑毛病!看看这个图片按钮在不同浏览器的缩放状态下表现如何?方便起见,我只把出问题的状态贴出来。
其实已经可以隐约预见,前面的测试还只是测试浏览器对纯CSS的解析,渲染对象基本上都是些矢量的线和块,而现在要测试的页面,除了浏览器解析CSS的能力外,还要考验浏览器的位图渲染能力,所以出问题的几率理应更大一些才是。
| IE7 |  测试结论: 相当神奇!IE7本来有的毛病在这里当然不会消失,比如小比例下的两个按钮粘连一起。 但是在对图片的渲染上,竟然做得如此完美!不论在任何比例下渲染出的背景图片都非常的精准、流畅和圆润! 我震惊了! |
| IE8 | 测试结论:IE8除多了在10%比例下文字会断行这个毛病之外,其他比例下的缩放表现与IE9如出一辙。 虽然可能具体效果小有差别,但是表现形式却是一样的,都是对背景图片渲染出现了偏差造成人的视觉误差。 为了节省大家的时间,请具体参看下面的IE9截图吧 |
| IE9 |  测试结果:IE9在不同缩放状态下都出现了背景图片对齐“错位”的问题,放大到500%后几乎消失; 仔细观察一下你会发现这种错位其实是对背景图片渲染效果差异造成的视觉错位! 不信我们对上图“偏移”较为严重的70%那张图进行截图和放大来看:  事实证明,IE9对背景图片的渲染能力还有待于提升! |
| Firefox |  测试结论:有些意外的是,渲染CSS块表现完美的Firefox在渲染图片时遇到了挑战! 面对这个挑战时,Firefox跟IE8和IE9几乎是一样的表现,当然好像相比IE8和IE9略微好一点点。 出现这种“视觉误差”的原因前面已经分析过,截图放大后也得以证实。 Firefox也要加油啊! |
| Opera |  测试结论:Opera在缩小渲染的时候表现依然完美,但是在放大时出现了问题。 A 、从120%开始,按钮Left与Center中间出现了一条裂缝,这个问题较为严重; B 、放大到一定程度后按钮右侧渲染出现了超限,本来设定为no-repeat的背景被渲染多了一块! 验证后发现,若按钮高度超过背景高度,渲染时按钮下侧同样会有类似的问题! 裂了!它竟然裂了!无法接受呀! |
| Chrome | 测试结果: 一张图说明所有问题,我是不是很聪明啊,哈哈哈! 你裂的惊天动地,裂的无以伦比,裂的花样百出啊! |
| Safari | 测试结果:Safari还是比Chrome聪明,虽然同样用了Webkit内核,但结果却不同! 显然Safari对图片的渲染要比Chrome更好一些。 Safari也裂了!裂的却比Chrome优雅! |
测试小结:
这次测试估计会刺激到很多人,我就是其中之一!还是总结一下吧:
A 、IE8、IE9相比IE7应该是修改了相当大一部分页面解析引擎,是的,IE终于比较“标准了”,可是你为什么把IE7那完美的背景图片渲染能力也给丢弃了呢?
B 、Firefox在页面缩放时的图片背景渲染也不比现在的IE8和9强多少,距离“最标准最完美的浏览器”还差了很多呢。
C 、最让人大跌眼镜的是Chrome和Safari,号称最快的浏览器,怎么能光顾快而不求质量呢,那千奇百怪的裂缝啊,让人忍无可忍有木有!
D 、Opera整体表现还是很棒的,不过秉承了它一贯的风格,就连犯错也犯的比较另类,一条似有若无的裂缝也就罢了,渲染超界您还是头一份儿。
4、这个页面在智能手机浏览器上究竟表现如何?
您可以理解为我要针对本文第二部分所阐述的现实意义给出例证了!
相信有人在看过我前文对智能手机与网页缩放渲染差别的描述之后,还是没有直观的感受,OK,现在我给来点刺激的,为您奉上两大智能手机,四大智能机浏览器的真实表现!
先来看iPhone的Safari Mobile!
A 、iPhone 竖屏默认比例和放大后的效果对比(两个都裂了):

B 、iPhone横屏默认比例和放大后的比例效果对比(裂的更离谱):

有点无语了吧?是不是对iPhone有点失望?我们再来看看Android下的效果!
A 、Android自带浏览器竖屏默认和放大状态(都不错,很完美)

B 、Android自带浏览器横屏默认和放大状态(依然很完美)

同样是Webkit内核,谷歌在Android内置的这个浏览器表现比他在电脑中的版本可强了太多了!
C 、Android版Firefox竖屏及其放大效果(放大时出现渲染视觉位移,跟电脑版Firefox一个德行)

D 、Android版Firefox横屏及其放大效果(放大时出现渲染视觉位移,跟电脑版Firefox一个德行)

E 、Android版Opera竖屏及其放大效果(放大时出现出现裂缝,跟电脑上一样)

F 、Android版Opera横屏及其放大效果(放大时左边出现裂缝,右侧超限渲染也跟电脑保持了一致)


小结一下:
总结iPhone和Android浏览器的表现,我们发现:
A 、在手机上直接访问web页面的时候,竖屏状态下的默认页面和元素及文字大小,基本不具备可读性,必须要放大!
B 、在横屏状态下默认页面元素及文字大小,勉强可读,但一般人也通常习惯放大阅读,换言之,手机上访问web页面基本都需要放大浏览。
C 、手机版的Safari、Firefox、Opera,基本上保留了其在电脑版上的同样毛病,因此,手机上浏览页面进行放大渲染一般都会出现前文所述的问题!
D 、Android原生自带的浏览器虽然是Webkit内核,但却进行了特殊优化,表现优异!
E 、上述事实再次证明,讨论浏览器缩放渲染页面的效果差异是绝对有其实际意义的!
5、汇总一下,前面测试出现的问题哪些可以接受,哪些必须解决?
个人的意见和想法,不保证100%适用他人:
A 、浏览器小比例的缩小状态(比如50%以下)下出现的渲染异常几乎都可以忽略:一来电脑上的访问可能有略微缩小的需求,但不会缩小太多,二来智能手机浏览器上根本就没有缩小需求(本来已经很小导致几乎无法浏览),这样的话,IE7的小比例渲染粘连和文字超出边界,IE8的小比例渲染文字换行,Chrome小比例状态下的文字折行基本可以忽略了;
B 、由于渲染效果导致的视觉偏差也基本可以忽略,因为这种偏差不会破坏页面元素的整体感,只是让人感觉有些不爽而已,当然了,能找个办法尽量降低这种破坏最好了,至于怎么做我们会在后面分析。这样,IE8/IE9/Firefox出现的渲染偏移问题我们可以暂时无视了。
C 、在Opera身上出现的超界渲染问题,只在很高的放大比例下才能发现,我们姑且对它宽容一些吧!