巨文!瀏覽器自身的BUG —— 不同瀏覽器在頁面縮放狀態(tài)下的渲染差異分析!讓你的網(wǎng)站在iPhone和Android上同樣完美!
Posted on 2011-07-25 11:03 隨它去吧 閱讀(26273) 評(píng)論(63) 收藏 舉報(bào)過度追求瀏覽器兼容其實(shí)就是拿不同瀏覽器開發(fā)者的個(gè)性或Bug懲罰自己!
前言
Web Developers 往往會(huì)因?yàn)樽约旱淖髌窡o法“完美兼容”多個(gè)瀏覽器而苦惱不已,然后責(zé)怪自己水平不夠或者M(jìn)SIE把你慣壞毒害了以至于無法寫出“標(biāo)準(zhǔn)的HTML+CSS+JS”!
但事實(shí)上,很多所謂的兼容性問題未必都是 Web Developer 自己造成的,也會(huì)有瀏覽器本身的問題!畢竟瀏覽器開發(fā)商也是人,也會(huì)犯錯(cuò)誤,他們的軟件同樣會(huì)有Bug,唯一不同的是,他們所犯的錯(cuò)誤往往會(huì)“懲罰”和困擾數(shù)以千萬計(jì)的下游Web開發(fā)者!
當(dāng)然了,話說回來,就算瀏覽器自己犯了錯(cuò)誤,也不能作為 Web Developer 不去考慮兼容性的借口,畢竟你不能告訴網(wǎng)站用戶“您眼前的頁面顯示不完美現(xiàn)象將會(huì)在下一版本的Firefox/Opera/Chrome中得到解決,請(qǐng)耐心等待新版本的發(fā)布……”,開個(gè)玩笑:)
因此研究不同瀏覽器各自的特點(diǎn)及其所犯錯(cuò)誤的表現(xiàn)總是有必要的。
下面說說我怎么會(huì)想到研究這個(gè)問題的。
目前正在開發(fā)的網(wǎng)站產(chǎn)品對(duì)用戶體驗(yàn)和交互水準(zhǔn)要求比較高,網(wǎng)站會(huì)用到許多有特色的自定義控件,然后在我對(duì)這些控件進(jìn)行封裝(采用 jQuery plugin 的形式)的時(shí)候遇到了一系列瀏覽器兼容方面的問題。
事實(shí)上這已經(jīng)不是單純的瀏覽器兼容性問題了,而是瀏覽器自身對(duì)同樣的Html+CSS代碼渲染時(shí)出現(xiàn)了問題(問題看似小問題,但是對(duì)實(shí)際應(yīng)用中的用戶界面破壞很嚴(yán)重)。具體說就是:
當(dāng)用戶進(jìn)行頁面縮放瀏覽的時(shí)候,即便同一個(gè)瀏覽器軟件,在不同縮放比例下渲染出的效果也是不一致的,會(huì)出現(xiàn)各種各樣的毛病,造成討厭的視覺效果破壞。
然后為了徹底解決這種類型的問題及其造成的破壞,我不得不從根本上去找原因,找解決方案,于是就有了這篇文章。
一、遇到問題的jQuery插件
上面提到我在開發(fā)時(shí)遇到問題的 jQuery plugin 之一是一個(gè)“庸俗的” Button ,說它庸俗是因?yàn)檫@樣的插件目前在 jQuery 的世界里至少已經(jīng)有數(shù)以萬計(jì)了,但是我卻還是沒能找到一個(gè)真正完美的,或者說能讓我滿意的,也許骨子里的真正原因是人都更希望使用自己可控制的東西吧。
簡單介紹一下這個(gè) Button plugin :為了支持豐富的視覺效果和更容易在頁面中進(jìn)行控制,我采用Div來模擬一個(gè)“四態(tài)(normal,hover,pressdown,disabled)按鈕”,你只需要通過改變CSS,就可以創(chuàng)建出簡潔的文本按鈕,通過CSS結(jié)合使用背景圖片更能夠模擬出各種獨(dú)具特色的按鈕形態(tài),關(guān)于它,后面我會(huì)另開文章介紹,這里就不羅嗦了。
嚴(yán)格來說,一個(gè)具有通用性的按鈕應(yīng)當(dāng)采用九宮格的“四角固定,中間區(qū)域自動(dòng)拉伸”模式來進(jìn)行渲染,這樣才能使得按鈕可以隨意控制高度和寬度,并且在不同尺寸下都能夠表現(xiàn)完美,但是 Web 開發(fā)有其獨(dú)特性,我們這個(gè)按鈕只需要能夠滿足自動(dòng)延展寬度就行,故而采用“左中右三段渲染”的方式進(jìn)行開發(fā)。
因此,在這里您只需要記住我們是用3個(gè)Div來分別模擬按鈕的左中右樣式即可。
作為一個(gè)按鈕,當(dāng)然不僅僅是模擬一個(gè) Button look Face 那么簡單,它還要能夠?qū)崿F(xiàn)形態(tài)變化,響應(yīng)鼠標(biāo)事件乃至鍵盤動(dòng)作,以此來宣示自己的按鈕身份并實(shí)現(xiàn)相應(yīng)的功能。然而這些并不是本文的講述重點(diǎn),本文只關(guān)注外觀模擬的部分,完整的 Button Plugin 開發(fā)文章,會(huì)在今后放出。
二、本文所討論問題的現(xiàn)實(shí)意義
肯定有人會(huì)覺得,你非要用 Div 去模擬一個(gè) Button 效果,這分明就是自尋煩惱,你這個(gè)例子根本不具有代表性,因此也說明不了什么問題。
真的是這樣嗎?未必見得吧!就算用 Div 模擬 Button 這件事兒本身是我自己閑的蛋疼,可是我總歸是在使用 Html+CSS 去實(shí)現(xiàn)一個(gè)視覺效果,這一點(diǎn)你無法否認(rèn)吧。而 CSS 對(duì)于網(wǎng)頁來講,其作用無非就是幫助頁面排版布局,與Html一起為用戶展現(xiàn)出友好優(yōu)雅的視覺效果而已。那么既然在我實(shí)現(xiàn)這個(gè)視覺效果的時(shí)候遇到了問題,別人在實(shí)現(xiàn)其他視覺效果的時(shí)候同樣也會(huì)存在問題,我這里是模擬按鈕出問題,別人那里就有可能是頁面模塊對(duì)齊出現(xiàn)錯(cuò)位,影響會(huì)更大!這就是本文的現(xiàn)實(shí)意義所在!
當(dāng)然了,也許還有善于抓漏洞的朋友會(huì)說“你這個(gè)所謂的‘不同縮放比例下的渲染效果差異’只有在用戶不斷改變網(wǎng)頁大小的時(shí)候才會(huì)出現(xiàn),事實(shí)上又會(huì)有多少用戶會(huì)像你一樣閑的蛋疼,逮著一個(gè)網(wǎng)頁縮來放去呢,因此這點(diǎn)小差別一般用戶根本就不會(huì)有機(jī)會(huì)感知的到,你這么斤斤計(jì)較又是何苦呢?”
聰明!精彩!貌似合情合理且又絲絲入扣!
然而我的答案是這樣的:
1、你所描述的情況基本屬實(shí),但是這能夠成為瀏覽器渲染頁面可以不嚴(yán)謹(jǐn)?shù)慕杩趩幔侩y道某些瀏覽器一方面宣稱支持這標(biāo)準(zhǔn)那規(guī)范,對(duì)“不標(biāo)準(zhǔn)”的微軟大加鞭撻,另一方面卻又對(duì)自己要求降低嗎?
我就想問一句:憑什么我寫的無錯(cuò)的、且“標(biāo)準(zhǔn)的” CSS 和 HTML ,你們?cè)诓煌s放比例下給我渲染出來卻不一樣?
(抱歉,吐槽到此結(jié)束)
2、為了避免有人說我只會(huì)講大道理,給出兩個(gè)更直觀的理由:
- A、現(xiàn)在 iPhone 手機(jī)和 Android 智能手機(jī)大行其道,對(duì)幾乎所有網(wǎng)站來講,使用這類設(shè)備上網(wǎng)訪問的用戶比例已經(jīng)在不斷提升,而且還將持續(xù)大幅提升!而目前為止并非所有網(wǎng)站都有能力為用戶提供一個(gè)移動(dòng)終端的專用版本(別跟我提 Wap ,玩這種手機(jī)的人絕對(duì)不會(huì)對(duì) Wap 網(wǎng)站感興趣,因?yàn)?Wap 體現(xiàn)不出他們手機(jī)的優(yōu)越性),所以絕大多數(shù)這類用戶都會(huì)用他們的手機(jī)瀏覽器( Safari Mobile 或者 Android 自帶的 Webkit 內(nèi)核的瀏覽器)來直接訪問你的Web網(wǎng)站,而無論 iPhone 還是 Android 上的手機(jī)瀏覽器都有自動(dòng)縮放頁面的功能(當(dāng)然這是因?yàn)槭謾C(jī)的屏幕分辨率?。藭r(shí)縮放后的頁面渲染效果就顯得至關(guān)重要了!比如你網(wǎng)頁上一個(gè)140像素寬的按鈕,經(jīng)過 iPhone 的縮小適應(yīng)屏幕寬度之后就只有一點(diǎn)點(diǎn)了,而你想準(zhǔn)確的點(diǎn)擊操作它的話一般都會(huì)進(jìn)行放大操作,而這時(shí),按鈕撕裂了……
- B、臺(tái)式電腦用戶都在大幅提高自己的配置,顯示器21寸以下你都不好意思跟人打招呼,23寸才算馬馬虎虎,分辨率自然是1920*1080了,然而在這種分辨率下看網(wǎng)頁的默認(rèn)字體會(huì)有多吃力你想過么?怎么辦?放大網(wǎng)頁唄,多簡單啊,按住Ctrl+鼠標(biāo)滾輪一滾,哇,放大的文字好牛逼!等等……什么?按鈕撕裂了?太尼瑪煞風(fēng)景了!
好了,看完這兩條依然認(rèn)為這個(gè)問題沒有意義的筒子們,您可以出門右拐了,這篇文章對(duì)您沒啥用,真的……
三、瀏覽器測(cè)試環(huán)境
瀏覽器兼容性測(cè)試是個(gè)很討厭的工作,首先環(huán)境搭建就很煩:
我在自己的 Win2003 上面安裝了 IE8,Chrome11,Firefox5,Opera11,Safari5,又在虛擬機(jī)上安裝了 IE6,IE7,然后還可以使用別人 Win7 上的 IE9 ,這樣就基本覆蓋了 Windows 上面的常用瀏覽器,也將作為我的測(cè)試環(huán)境。
對(duì)于 Linux 來說,常用瀏覽器無非也是 Firefox,Opera,Webkit 這三個(gè)內(nèi)核,他們的表現(xiàn)與各自的 Windows 版本相比并不會(huì)有本質(zhì)不同。蘋果的 Mac OS 所使用的 Safari 與 Windows 下的 Safari 一樣大同小異。因此我就沒有單獨(dú)安裝這兩個(gè)系統(tǒng)進(jìn)行測(cè)試,以后有機(jī)會(huì),這一課我會(huì)補(bǔ)上的。
當(dāng)然了,現(xiàn)在這個(gè)時(shí)代,要測(cè)試瀏覽器兼容性,你還少不了 iPhone ,運(yùn)行在 iPhone 上面的 Safari Mobile 目前可是相當(dāng)大的一個(gè)訪問群體哦,另外還有我的 Android ,除了其自帶一個(gè) Google 自己開發(fā)的以 Webkit 為內(nèi)核的瀏覽器,還有 Firefox 和 Opera 分別為 Android 平臺(tái)開發(fā)了響應(yīng)版本的瀏覽器,這次把它們一并納入測(cè)試范圍!唯一有點(diǎn)遺憾的是微軟的 WP7 ,暫時(shí)沒有機(jī)器可以進(jìn)行測(cè)試,后面我會(huì)附上頁面源碼,希望有條件的筒子幫我測(cè)試一下。
總結(jié)一下,現(xiàn)在我們有了
IE6/IE7/IE8/IE9/Firefox5/Opera11/Safari5/Chrome11/Safari Mobile/Firefox Mobile/Opera Mobile/Chrome Mobile
作為測(cè)試環(huán)境!
四、發(fā)現(xiàn)和解決問題的詳細(xì)過程
1、首先用4個(gè)Div和純CSS來模擬一個(gè)簡單按鈕的外形
由于本文旨在分析瀏覽器頁面渲染的差別,故而按鈕的狀態(tài)變化、事件響應(yīng)等在這里不做實(shí)現(xiàn),這個(gè)頁面分別采用了float和absolute兩種布局對(duì)按鈕進(jìn)行了模擬,先看代碼:
<!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;
}
/*按鈕左中右容器基本樣式設(shè)定*/
.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>塊里面,而具體到兩種不同布局方式的差別部分,為了直觀起見,我直接寫在了標(biāo)簽的style屬性里面。下面看效果:
| IE6 |
|
| IE7 |
|
| IE8 |
|
| IE9 |
|
| Firefox |
|
| Opera |
|
| Chrome |
|
| Safari |
|
大家看到了,在各瀏覽器標(biāo)準(zhǔn)顯示比例下解析出來的效果接近一致,非常"完美"!等等,這就行了么?顯然不是的,否則就不會(huì)有這篇文章存在的價(jià)值了。
另外,其實(shí)仔細(xì)看的話,不同瀏覽器對(duì)頁面渲染的區(qū)別已經(jīng)初露端倪,比如:
A、不同瀏覽器對(duì)默認(rèn)字體的選擇是不一樣的,有的是宋體,有的是雅黑……好吧好吧,這個(gè)可以理解,算我吹毛求疵,我該在CSS指定默認(rèn)字體的……
B、對(duì)line-height的解析和渲染,各瀏覽器并不一致,有興趣的可以自己截圖對(duì)比一下,尤其是IE系列,相比其他瀏覽器總會(huì)有向上偏移,除IE9之外的其他IE版本,通常宋體會(huì)上偏2個(gè)像素,雅黑會(huì)上偏1個(gè)像素(所以你知道的,為了美觀起見,盡量用雅黑吧)
C、對(duì)于<br/>的解析,高度不盡相同,當(dāng)然這個(gè)并不十分影響視覺效果,但是依然體現(xiàn)了各瀏覽器開發(fā)商的“不負(fù)責(zé)任”,你們整天罵人家微軟不遵守標(biāo)準(zhǔn),你們倒是好好遵守啊。
2、對(duì)模擬出的簡單按鈕效果在不同瀏覽器下分別進(jìn)行縮放測(cè)試
| IE6 |
IE6無整頁縮放功能,測(cè)試忽略 |
| IE7 |
頁面在小于(含)50%比例下顯示的時(shí)候<br />效果消失,兩個(gè)按鈕粘連在一起; 在最小10%的顯示比例下文字渲染還超出了按鈕邊界; 在放大比例的時(shí)候?qū)?lt;br />的渲染處理不好,高倍顯示下這個(gè)換行非常夸張; 除了上述三個(gè)小問題外,其他比例均可以算作顯示良好。 我的打分:70 |
| IE8 |
不過小問題依然存在,那就是在10%比例下,文字出現(xiàn)了換行,雖然無實(shí)際意義,也算一點(diǎn)小遺憾吧; 除此之外,可以看到IE8對(duì)放大時(shí)兩個(gè)div之間<br />的間隙做了更加人性化的處理,不像IE7那么生硬了。 我的打分:85 |
| IE9 |
不知道微軟有沒有刻意處理這些,但是之前IE7和IE8出現(xiàn)的小問題全部消失了 ! 我的打分:98(留點(diǎn)改進(jìn)空間給微軟吧) |
| Firefox |
跟IE9相比,除了縮放倍數(shù)受限一點(diǎn)之外,在渲染效果上不相上下,很贊! 我的打分:95(縮放倍數(shù)受限扣3分) |
| Opera |
其渲染質(zhì)量與IE9和Firefox不相上下。 我的打分:98(與IE9打平) |
| Chrome |
在這12個(gè)縮放級(jí)別里面總共出現(xiàn)了如下多的問題,讓我比較失望: a、50%和57%兩個(gè)比例下, 文字錯(cuò)行; b、57%,69%,144%,207%四個(gè)比例下,F(xiàn)loat定位方式Center和Right之間出現(xiàn)了 1像素的縫隙; c、而在248%和298%兩個(gè)比例下,F(xiàn)loat定位方式出現(xiàn)了2像素的縫隙! 不僅如此,連Absolute方式也出現(xiàn)了1像素縫隙! 我的打分:50 |
| Safari |
不過Safari畢竟聰明,他把縮放限制為10個(gè)級(jí)別,甚至你連縮放比例都看不到,囧! 不過借此倒是隱藏了文字折行的bug,只剩下裂縫問題了: a 、第1,第2,第6,第8級(jí)別Float方式出現(xiàn)1像素裂縫; b 、第9,第10級(jí)別,F(xiàn)loat方式的裂縫擴(kuò)大到2像素,而absolute方式也出現(xiàn)了1像素裂縫! 我的打分:55 |
測(cè)試小結(jié):
A、在瀏覽器渲染能力方面,其實(shí)微軟一直在進(jìn)步,他追求的高容錯(cuò)能力的的確確在為用戶體驗(yàn)考慮,而這卻成了別人攻擊他“不標(biāo)準(zhǔn)”的口實(shí)!
B、Firefox和Opera這兩個(gè)有著深厚底蘊(yùn)的家伙的確手里有真功夫,然而這還只是個(gè)開始,更多測(cè)試在后邊。
C、一直為人所推崇的Webkit其實(shí)遠(yuǎn)沒有那么完美,只不過人家抓住了“快”這一噱頭和賣點(diǎn)!再加上無論Apple還是Google都是善于宣傳推廣灌輸?shù)母呤郑浴?/span>
D、從CSS使用角度來講,F(xiàn)loat的布局方式更容易出偏差!如果您為了圖文布局方便,盡管大膽的Float就行了,可如果是想實(shí)現(xiàn)某些漂亮的視覺效果,那么請(qǐng)三思。
3、純CSS的渲染已經(jīng)出現(xiàn)問題,那么如果換成圖片模擬按鈕呢?
前面用純CSS模擬的按鈕出問題了,很不幸!那么如果我用圖片來進(jìn)行模擬呢?會(huì)好一點(diǎn)?或者更糟?讓測(cè)試結(jié)果來證明吧!
下面我寫一個(gè)新的頁面,使用圖片來模擬按鈕的Normal態(tài)(其他三態(tài)原理相同),先看看這個(gè)背景圖片

這是一個(gè)png格式的圖片,寬6像素,高度105像素,背景透明,按鈕實(shí)體高度為32px,我在設(shè)計(jì)的時(shí)候是按照35像素做的,原因后面會(huì)有解釋。
然后修改CSS和網(wǎng)頁代碼,使之能夠模擬一個(gè)圖片按鈕的左中右三段(之所以采用三段的方式來模擬是因?yàn)槲覀兎庋b的按鈕是希望寬度不受限制的,因此固定寬度背景圖片搞不定),下面是全部代碼(聽取批評(píng),給body設(shè)置了默認(rèn)字體為雅黑):
<!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;
}
/*按鈕左中右容器基本樣式設(shè)定*/
.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>
正常比例狀態(tài)下的按鈕效果圖我就不一一截圖貼出來了,除了IE6不支持透明png圖片有點(diǎn)丑之外都很完美:

說到IE6,我以后開發(fā)的Web應(yīng)用幾乎都不再考慮它了,從現(xiàn)在的形勢(shì)來看,IE6被放棄將是很短時(shí)間內(nèi)的事情,我樂意提前一步。
下面要做的是我不怎么喜歡的,給瀏覽器挑毛病!看看這個(gè)圖片按鈕在不同瀏覽器的縮放狀態(tài)下表現(xiàn)如何?方便起見,我只把出問題的狀態(tài)貼出來。
其實(shí)已經(jīng)可以隱約預(yù)見,前面的測(cè)試還只是測(cè)試瀏覽器對(duì)純CSS的解析,渲染對(duì)象基本上都是些矢量的線和塊,而現(xiàn)在要測(cè)試的頁面,除了瀏覽器解析CSS的能力外,還要考驗(yàn)瀏覽器的位圖渲染能力,所以出問題的幾率理應(yīng)更大一些才是。
| IE7 |
但是在對(duì)圖片的渲染上,竟然做得如此完美!不論在任何比例下渲染出的背景圖片都非常的精準(zhǔn)、流暢和圓潤! 我震驚了!
|
| IE8 |
雖然可能具體效果小有差別,但是表現(xiàn)形式卻是一樣的,都是對(duì)背景圖片渲染出現(xiàn)了偏差造成人的視覺誤差。 為了節(jié)省大家的時(shí)間,請(qǐng)具體參看下面的IE9截圖吧 |
| IE9 |
仔細(xì)觀察一下你會(huì)發(fā)現(xiàn)這種錯(cuò)位其實(shí)是對(duì)背景圖片渲染效果差異造成的視覺錯(cuò)位! 不信我們對(duì)上圖“偏移”較為嚴(yán)重的70%那張圖進(jìn)行截圖和放大來看:
|
| Firefox |
面對(duì)這個(gè)挑戰(zhàn)時(shí),F(xiàn)irefox跟IE8和IE9幾乎是一樣的表現(xiàn),當(dāng)然好像相比IE8和IE9略微好一點(diǎn)點(diǎn)。 出現(xiàn)這種“視覺誤差”的原因前面已經(jīng)分析過,截圖放大后也得以證實(shí)。
|
| Opera |
A 、從120%開始,按鈕Left與Center中間出現(xiàn)了一條裂縫,這個(gè)問題較為嚴(yán)重; B 、放大到一定程度后按鈕右側(cè)渲染出現(xiàn)了超限,本來設(shè)定為no-repeat的背景被渲染多了一塊! 驗(yàn)證后發(fā)現(xiàn),若按鈕高度超過背景高度,渲染時(shí)按鈕下側(cè)同樣會(huì)有類似的問題! 裂了!它竟然裂了!無法接受呀! |
| Chrome |
你裂的驚天動(dòng)地,裂的無以倫比,裂的花樣百出??!
|
| Safari |
顯然Safari對(duì)圖片的渲染要比Chrome更好一些。
|
測(cè)試小結(jié):
這次測(cè)試估計(jì)會(huì)刺激到很多人,我就是其中之一!還是總結(jié)一下吧:
A 、IE8、IE9相比IE7應(yīng)該是修改了相當(dāng)大一部分頁面解析引擎,是的,IE終于比較“標(biāo)準(zhǔn)了”,可是你為什么把IE7那完美的背景圖片渲染能力也給丟棄了呢?
B 、Firefox在頁面縮放時(shí)的圖片背景渲染也不比現(xiàn)在的IE8和9強(qiáng)多少,距離“最標(biāo)準(zhǔn)最完美的瀏覽器”還差了很多呢。
C 、最讓人大跌眼鏡的是Chrome和Safari,號(hào)稱最快的瀏覽器,怎么能光顧快而不求質(zhì)量呢,那千奇百怪的裂縫啊,讓人忍無可忍有木有!
D 、Opera整體表現(xiàn)還是很棒的,不過秉承了它一貫的風(fēng)格,就連犯錯(cuò)也犯的比較另類,一條似有若無的裂縫也就罷了,渲染超界您還是頭一份兒。
4、這個(gè)頁面在智能手機(jī)瀏覽器上究竟表現(xiàn)如何?
您可以理解為我要針對(duì)本文第二部分所闡述的現(xiàn)實(shí)意義給出例證了!
相信有人在看過我前文對(duì)智能手機(jī)與網(wǎng)頁縮放渲染差別的描述之后,還是沒有直觀的感受,OK,現(xiàn)在我給來點(diǎn)刺激的,為您奉上兩大智能手機(jī),四大智能機(jī)瀏覽器的真實(shí)表現(xiàn)!
先來看iPhone的Safari Mobile!
A 、iPhone 豎屏默認(rèn)比例和放大后的效果對(duì)比(兩個(gè)都裂了):

B 、iPhone橫屏默認(rèn)比例和放大后的比例效果對(duì)比(裂的更離譜):

有點(diǎn)無語了吧?是不是對(duì)iPhone有點(diǎn)失望?我們?cè)賮砜纯碅ndroid下的效果!
A 、Android自帶瀏覽器豎屏默認(rèn)和放大狀態(tài)(都不錯(cuò),很完美)

B 、Android自帶瀏覽器橫屏默認(rèn)和放大狀態(tài)(依然很完美)

同樣是Webkit內(nèi)核,谷歌在Android內(nèi)置的這個(gè)瀏覽器表現(xiàn)比他在電腦中的版本可強(qiáng)了太多了!
C 、Android版Firefox豎屏及其放大效果(放大時(shí)出現(xiàn)渲染視覺位移,跟電腦版Firefox一個(gè)德行)

D 、Android版Firefox橫屏及其放大效果(放大時(shí)出現(xiàn)渲染視覺位移,跟電腦版Firefox一個(gè)德行)

E 、Android版Opera豎屏及其放大效果(放大時(shí)出現(xiàn)出現(xiàn)裂縫,跟電腦上一樣)

F 、Android版Opera橫屏及其放大效果(放大時(shí)左邊出現(xiàn)裂縫,右側(cè)超限渲染也跟電腦保持了一致)


小結(jié)一下:
總結(jié)iPhone和Android瀏覽器的表現(xiàn),我們發(fā)現(xiàn):
A 、在手機(jī)上直接訪問web頁面的時(shí)候,豎屏狀態(tài)下的默認(rèn)頁面和元素及文字大小,基本不具備可讀性,必須要放大!
B 、在橫屏狀態(tài)下默認(rèn)頁面元素及文字大小,勉強(qiáng)可讀,但一般人也通常習(xí)慣放大閱讀,換言之,手機(jī)上訪問web頁面基本都需要放大瀏覽。
C 、手機(jī)版的Safari、Firefox、Opera,基本上保留了其在電腦版上的同樣毛病,因此,手機(jī)上瀏覽頁面進(jìn)行放大渲染一般都會(huì)出現(xiàn)前文所述的問題!
D 、Android原生自帶的瀏覽器雖然是Webkit內(nèi)核,但卻進(jìn)行了特殊優(yōu)化,表現(xiàn)優(yōu)異!
E 、上述事實(shí)再次證明,討論瀏覽器縮放渲染頁面的效果差異是絕對(duì)有其實(shí)際意義的!
5、匯總一下,前面測(cè)試出現(xiàn)的問題哪些可以接受,哪些必須解決?
個(gè)人的意見和想法,不保證100%適用他人:
A 、瀏覽器小比例的縮小狀態(tài)(比如50%以下)下出現(xiàn)的渲染異常幾乎都可以忽略:一來電腦上的訪問可能有略微縮小的需求,但不會(huì)縮小太多,二來智能手機(jī)瀏覽器上根本就沒有縮小需求(本來已經(jīng)很小導(dǎo)致幾乎無法瀏覽),這樣的話,IE7的小比例渲染粘連和文字超出邊界,IE8的小比例渲染文字換行,Chrome小比例狀態(tài)下的文字折行基本可以忽略了;
B 、由于渲染效果導(dǎo)致的視覺偏差也基本可以忽略,因?yàn)檫@種偏差不會(huì)破壞頁面元素的整體感,只是讓人感覺有些不爽而已,當(dāng)然了,能找個(gè)辦法盡量降低這種破壞最好了,至于怎么做我們會(huì)在后面分析。這樣,IE8/IE9/Firefox出現(xiàn)的渲染偏移問題我們可以暫時(shí)無視了。
C 、在Opera身上出現(xiàn)的超界渲染問題,只在很高的放大比例下才能發(fā)現(xiàn),我們姑且對(duì)它寬容一些吧!
D 、頁面元素之間的裂縫絕對(duì)不可以接受!尤其是放大狀態(tài)下出現(xiàn)的裂縫,更加讓人無法容忍!
根據(jù)這一要求,電腦上的Opera、Chrome、Safari都是不合格的!手機(jī)上的Safari、Opera也同樣不合格!我們強(qiáng)烈要求瀏覽器開發(fā)商加以改進(jìn)!
按照我的判決,IE要去面壁,F(xiàn)irefox必須懺悔,Opera應(yīng)該去撞墻,Safari可以去死,Chrome直接車裂了吧!
補(bǔ)充一句:該車裂的是電腦上的Chrome,Android上那個(gè)谷歌的“私生子”,沒敢公開身份和姓名的Chrome卻表現(xiàn)完美,不在其列。
6、嘗試解決前面測(cè)試總結(jié)出的問題
問題出現(xiàn)了,總要去解決,抱怨是沒用的,等待瀏覽器自己的改進(jìn)那更是不靠譜的事情?,F(xiàn)在我們已經(jīng)明確,目標(biāo)如下:
A 、元素之間的裂縫問題必須解決;
B 、渲染出現(xiàn)的視覺偏差盡量解決;
其中問題A在純CSS的環(huán)境中比較容易解決,給父容器設(shè)置一樣的背景色就可以掩蓋這個(gè)小缺憾,但是這個(gè)方法在圖片模擬按鈕的環(huán)境下行不通,尤其是背景圖有透明區(qū)域的情況下,這樣的背景疊加會(huì)異常丑陋(反而不如沒有Left和Right,一通到底的統(tǒng)一背景來的好看),而全部實(shí)色背景圖片模擬的按鈕又有太強(qiáng)的局限性。
問題B有些困難,我們放大觀察前面那些出現(xiàn)偏差的截圖就會(huì)發(fā)現(xiàn),偏差主要出現(xiàn)在Left、Right與Center交界部位的那幾個(gè)像素上,在本文的實(shí)例當(dāng)中,按鈕背景圖片寬度是6像素,事實(shí)上純粹屬于Left和Right的只有3個(gè)像素,其余延伸出的3個(gè)像素均與Center的背景完全一致,而正是這左右各延伸出的3個(gè)像素與Center背景在渲染時(shí)出現(xiàn)了不一致,最終導(dǎo)致視覺誤差。
怎么解決?
仔細(xì)觀察一下,其實(shí)所有瀏覽器在渲染時(shí)出現(xiàn)的裂縫沒有超過2像素的,那么通過強(qiáng)行對(duì)Div定位進(jìn)行偏移(比如Center向左偏移2個(gè)像素,同時(shí)寬度增加4像素,從而對(duì)Left和Right各覆蓋2像素),這種元素疊加的方式能否從視覺上解決這個(gè)問題呢?我們來試一下:
下面是修改過的代碼(由于兩個(gè)原因:一是Float定位有更大不確定性,二是absolute定位實(shí)現(xiàn)偏移和覆蓋更加方便,所以這里只對(duì)absolute定位方式進(jìn)行修改,F(xiàn)loat效果留作對(duì)比,另外考慮到本例圖片Left和Right分別只有3像素是有用的,我就干脆都給他強(qiáng)制偏移3像素看看)
<!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;
}
/*按鈕左中右容器基本樣式設(shè)定*/
.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: 3px; width: 194px;">Absolute方式模擬的按鈕</div>
</div>
</body>
</html>
下面是測(cè)試效果圖,這里只選取一些有代表性的截圖了。
| IE7 |
跟前面未加偏移的版本沒有任何區(qū)別!故而免圖!
|
| IE8 |
|
| IE9 |
參見上面IE8的截圖,IE9的改善甚至更明顯!
|
| Firefox |
|
| Opera |
|
| Chrome |
|
| Safari |
|
|
iPhone Safari Mobile |
|
|
Android 自帶瀏覽器 |
本來就很完美,免圖!
|
|
Android Firefox |
|
|
Android Opera Mobile |
|
到現(xiàn)在為止,我們幾乎可以說,通過偏移嘗試消除按鈕裂縫和視覺偏移的實(shí)驗(yàn)成功了!
7、有沒有遺留問題?
答案是確定的,有!什么問題?
前面的例子背景圖片使用了邊角透明的png圖片,所以渲染出來的結(jié)果可以成功的透出背景,視覺效果非常好,那么如果更進(jìn)一步,給背景圖片邊緣加上半透明的投影效果,那又會(huì)如何呢?我們繼續(xù)測(cè)試!
首先是修改添加了投影效果之后的背景圖(左右各讓出1個(gè)像素給投影,下面2個(gè)像素的投影)

對(duì)應(yīng)的CSS代碼和html代碼也略作修改(Left和Right的真實(shí)邊緣部分都變成了4像素,所以對(duì)應(yīng)的偏移和覆蓋也修正為2像素,按鈕高度變成了35像素,然后刪掉那個(gè)用不著的Float定位按鈕)
代碼如下:
<!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: 35px;
width: 200px;
position: relative;
}
/*按鈕左中右容器基本樣式設(shè)定*/
.Left, .Center, .Right{
background-image: url('btn_bg_shadow.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>
<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: 4px; width: 192px;">Absolute方式模擬的按鈕</div>
</div>
</body>
</html>
效果圖我們?cè)谶@里只找一個(gè)瀏覽器作為代表,就選Opera吧,大家知道前面Opera還有個(gè)渲染超界的問題呢:

上面是不帶陰影的按鈕效果,下面是帶了陰影的效果,對(duì)比一下,果然是帶陰影的效果更自然,跟背景融合更好,可是等一下……怎么感覺好像哪里有點(diǎn)不對(duì)?我們放大來看一下:

囧了!放大后發(fā)現(xiàn)三個(gè)問題:
A 、兩側(cè)Left和Right分別與Center重疊的部分陰影疊加造成比其他地方更重的顏色,活像鬧鐘的兩個(gè)支撐腿
B 、右側(cè)的渲染超界依然存在
C 、底下也出現(xiàn)了渲染超界(把按鈕高度改為34像素后消失)
問題A很容易理解,我們用疊加的方式來避免按鈕裂縫,那么半透明的陰影疊加在一起當(dāng)然會(huì)顯出雙重的效果。問題B也不意外,因?yàn)楸緛砭陀?,問題C就有些郁悶了。
解決方法嘗試結(jié)果:
嘗試結(jié)果1:
經(jīng)過多次試驗(yàn),把按鈕高度改為34像素,Opera底下的渲染超界消失(這就是我為什么明明按鈕加陰影高度是34像素,我卻要把背景圖做成35像素的原因了),但是右側(cè)的超界卻無法用同樣的方法解決!請(qǐng)看效果圖:

嘗試結(jié)果2:
對(duì)于問題A我唯一能想到的方案是一個(gè)笨辦法,把背景圖中Left和Right下部投影中可能會(huì)與Center投影重合的部分切掉(本文例子當(dāng)中是各2個(gè)像素),變成全透明,這樣可以避免所有瀏覽器下的“鬧鐘腿”問題了,當(dāng)然也會(huì)帶來一點(diǎn)負(fù)面的影響,就是在Chrome或者Safari中某些時(shí)候有可能會(huì)出現(xiàn)陰影部分1個(gè)像素的缺失,但是這個(gè)缺失相比重疊來講,幾乎從視覺上無法感知到。
先看裁切掉部分陰影后的背景圖:

再看最終的效果圖:

考慮到渲染超界的問題僅僅在 Opera 超高放大倍數(shù)時(shí)才會(huì)出現(xiàn),因此我們可以說,到目前為止,所有的遺留問題也基本有了解決方法,雖然可能還不很完美,但是沒關(guān)系,出現(xiàn)這些問題的原因本身不就是因?yàn)闉g覽器們自己不完美么?而且我們之前想出的種種解決方案也正是利用瀏覽器的不完美去彌補(bǔ)瀏覽器的不完美!就好像CSS Hack一樣!所以無需再對(duì)自己繼續(xù)苛求了!
五、總結(jié)和建議
這注定是一篇不會(huì)怎么惹人關(guān)注的文章,著眼點(diǎn)既不是技術(shù)前沿,也不是創(chuàng)新概念,從頭至尾都在跟幾個(gè)瀏覽器上的1個(gè)像素2個(gè)像素死較勁,很多人肯定覺得我故意在跟各大瀏覽器頂牛,有時(shí)候我也懷疑自己是不是真的閑的蛋疼:)
但其實(shí)我知道,之所以去鉆這個(gè)牛角尖,恰恰是因?yàn)槲易约赫嬲延脩趔w驗(yàn)放在了第一位!做一個(gè)真正的產(chǎn)品,沒有好的用戶體驗(yàn),哪怕你再好的創(chuàng)意,最終也會(huì)一事無成!什么是用戶體驗(yàn)?消滅掉這1個(gè)像素的偏差當(dāng)然不能等于好的用戶體驗(yàn),可是我卻知道可能就是那1像素的偏差會(huì)讓用戶體驗(yàn)變得很糟糕!
如果您是單純編寫代碼的程序員,可能不明白我說的是什么,但如果您做過產(chǎn)品經(jīng)理或者UED相關(guān)的工作,您會(huì)理解我的苦心。
呵呵,一不小心又開始吐槽了,書歸正傳,總結(jié)一下這篇長文所獲得的啟示吧:
1、現(xiàn)階段做互聯(lián)網(wǎng)產(chǎn)品,已經(jīng)不能僅僅考慮電腦平臺(tái)(Windows/Linux/Mac)上的瀏覽器兼容性了,智能手機(jī)和類平板電腦的產(chǎn)品同樣需要考慮;
2、小屏幕(7寸以下)便攜終端瀏覽器通常都會(huì)有縮放功能,而且默認(rèn)狀況下網(wǎng)頁都會(huì)被放大瀏覽,因此Web頁面效果不僅要看100%狀態(tài),還要放大看,本來很棒的視覺效果,沒準(zhǔn)兒一放大就走樣的很離譜;
3、建議盡量對(duì)大眾保有量較高且又與眾不同的設(shè)備和瀏覽器(比如iPhone和Android手機(jī))開發(fā)專用的適配版本網(wǎng)頁;
4、瀏覽器也會(huì)犯錯(cuò)誤,如果你的Web產(chǎn)品看起來在兼容性上有問題,其實(shí)不能排除是某個(gè)瀏覽器自身的問題,有時(shí)候你不得不去為他們的Bug背書;
5、不同瀏覽器在對(duì)頁面進(jìn)行縮放操作的時(shí)候渲染會(huì)出問題,本文就有一個(gè)很突出的例子,很多瀏覽器對(duì)CSS中Float和Absolute定位的解析和渲染并不十分精準(zhǔn),因此可能會(huì)造成頁面元素走形,而這其中Float又比Absolute更容易出問題;
6、同樣在縮放操作下,大多數(shù)瀏覽器對(duì)位圖的渲染差異就更大,這會(huì)帶來小屏幕設(shè)備上瀏覽時(shí)的視覺偏差,降低用戶體驗(yàn);
7、針對(duì)“由數(shù)個(gè)寬度不固定的連續(xù)元素組合而成的視覺效果”這類的處理需要(比如模擬按鈕、模擬導(dǎo)航欄、模擬窗體邊框、大圖片切割展示等),為了避免出現(xiàn)5和6所描述的問題,可以采用結(jié)合部2像素重疊的方法來避免割裂。
8、網(wǎng)頁中的半透明過渡圖片效果會(huì)非常的棒,不過在有可能拼接和重疊的地方使用起來要慎重,如果可以的話,盡量采用半透明層的方式來實(shí)現(xiàn)。
追求瀏覽器兼容性的本質(zhì)其實(shí)就是用它的一個(gè)缺憾去掩蓋另一個(gè)缺憾!
這篇折磨了我整個(gè)周末的文章終于到了收尾的階段,說實(shí)話很少這么費(fèi)心費(fèi)力的寫一篇技術(shù)文章,所以到了最后反而有些不舍得擱筆,本人技術(shù)有限,水平不高,文中難免出現(xiàn)偏頗乃至謬誤,望大家多多指正,不管怎樣,希望這篇文章所做的努力能夠?qū)Υ蠹叶嗌儆行﹩l(fā)乃至幫助,我就很欣慰了。
最后把本文用到的測(cè)試頁面代碼和圖片放在這里,有興趣的可以自己測(cè)試,點(diǎn)擊這里下載


























浙公網(wǎng)安備 33010602011771號(hào)