根據我的實踐經驗。如果你在寫HTML/CSS時候是按照W3C推薦的方式寫的,那么基本的瀏覽器兼容問題都是可以避免的。
這里主要考慮是的ie8-,個人目測Ie9+的渲染效果已經跟的上主流了。
測試ie兼容最好要在win7+上測試,因為winXP最高支持IE8。
這里貼出百度統計的瀏覽器市場份額:
PC端:
再給一張國外的
測試網址http://gs.statcounter.com/
目測谷歌是主流啊,變化平穩。排在第二的是IE8,Ie6的地位還是有的,不過占有率不高了,如果不是做學校政府機關方面的基本可以忽略不計了。
個人建議你的項目考慮是瀏覽器:谷歌,ie8+,Firefox,Safari,opera,360瀏覽器,搜狗。這些瀏覽器最好都用真實設備實測。
OK,現在我們就來寫點小代碼避免瀏覽器不兼容的問題吧。
DOCTYPE
首先要確保你的HTML頁面開始有DOCTYPE聲明。DOCTYPE告知瀏覽器使用什么樣的HTML或XHTML規范來解析HTML文檔。DOCTYPE還會對瀏覽器的渲染模式產生影響,不同的渲染模式會影響到瀏覽器對CSS甚至JS的解析。尤其是IE系列的瀏覽器,由DOCTYPE所決定的HTML頁面渲染可以差很多,可以把你的頁面弄個面目全非。
看下面的聲明,這是我以前常用的DOCTYPE聲明
<span style="font-family:SimSun;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"></span>
- DOCTYPE html :頁面的文檔類型是HTML
- PUBLIC:是公共的,可以個人家查看的,打開頁面右擊查看源代碼。
- "-//W3C//DTD XHTML 1.0 Transitional//EN":是w3c這個組織定義的 XHTML 1.0 過渡型 語言是英文
- http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd:可以到這個網址下面找到相關的規范
參考:
http://w3help.org/zh-cn/kb/001
http://w3help.org/zh-cn/casestudies/002
http://www.w3cschool.cn/tag_doctype.html
上面推薦使用(項目中都用這聲明了)
<span style="font-family:SimSun;"><!DOCTYPE html></span>
在我以前的項目里。后端的同志們老是覺得這個聲明沒啥用,總自作主張的把它刪掉,或者亂用這個聲明,因為即使你刪除或者亂用都不會報錯的,但是偏偏在某個瀏覽器下就出現這樣那樣的問題,找你過去看了半天,原來他把DOCTYPE聲明給刪除了,我真心想說靠。這是一個小細節,希望童鞋們都注意了。
解決方案:
使用頭部開始
<!DOCTYPE html>
使用meta標簽調節瀏覽器的渲染方式
IE8發布的時候,相對于IE6/7已經做出了相當大的改進,向w3c漫進很大一步。IE8發布的時候,當時很多的網站都是基于Ie6/7來做處理的,如果瞬間改為ie8渲染,有點不科學。所以ie8就加入了“兼容模式”功能,這樣就可以再Ie8瀏覽器中
使用Ie6/7的內核渲染頁面。但是對于現在的我們來說,我們是不需要這樣的。所以我們可以使用meta標簽來強制的讓Ie8使用最新的內核渲染頁面。
<span style="font-family:SimSun;"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"></span>
- IE=edge:使用最新的IE內核。
- chrome=1:如果安裝了谷歌就讓IE瀏覽器的外觀不變,內核渲染用谷歌。當然了官方的說法不是安裝了谷歌的瀏覽器。
國內的很多瀏覽器都是雙核瀏覽器,比如306瀏覽器,搜狗,它們是怎么決定用哪個內核來渲染頁面的呢?
這里引用了360瀏覽器幫助的一段文字來回答:
“由于眾所周知的情況,國內的主流瀏覽器都是雙核瀏覽器:基于Webkit內核用于常用網站的高速瀏覽。基于IE的內核用于兼容網銀、舊版網站。以360的幾款瀏覽器為例,我們優先通過Webkit內核渲染主流的網站,只有小量的網站通過IE內核渲染,以保證頁面兼容。在過去很長一段時間里,我們主要的控制手段是一個幾百k大小網址庫,一個通過長期人工運營收集的網址庫。
盡管我們努力通過用戶反饋、代碼標簽智能判斷技術提高瀏覽器的自動切核準確率。但是在很多情況下,我們仍然無法達到百份百正確。因此,我們新增加了一個控制手段:內核控制Meta標簽。只要你在自己的網站里增加一個Meta標簽,告訴360瀏覽器這個網址應該用哪個內核渲染,哪么360瀏覽器就會在讀取到這個標簽后,立即切換對應的內核。并將這個行為應用于這個二級域名下所有網址。
目前該功能已經在所有的360安全瀏覽器實現。我們也建議其它瀏覽器廠商一起支持這個實現。讓這個控制標簽成為行業標準。”
360瀏覽器建議我們采用webkit
<span style="font-family:SimSun;"><meta name="renderer" content="webkit"></span>
解決方案:
在任何頁面的頭部加上
<!-- 指定以最新的IE版本模式來顯示網頁 --> <meta http-equiv="X-UA-Compatible" content="IE=edge,<span style="font-family: SimSun;">chrome=1</span> " /> <!-- 360瀏覽器相關設置:http://se.360.cn/v6/help/meta.html --> <!-- 針對360瀏覽器的內核調用,強制調用極速模式 --> <meta name="renderer" content="webkit" /> <!-- 針對360瀏覽器強制調用IE標準模式 --> <!--[if lt IE 10]> <meta name="renderer" content="ie-stand" /> <![endif]--> <!--[if !IE]> <meta name="renderer" content="ie-stand" /> <!<![endif]-->
在火狐中注釋解析錯誤
標準做法
<span style="font-family:SimSun;">// 單行注釋 <!-- this is a comment --> // 多行注釋 <!-- and so is this one, which occupies more than one line --></span>
注意的是:
- 注釋元素的開始標簽"<!">和"--"之間不能有空白符存在,但是在其他瀏覽器中,就算有空白符也可以正確的識別。
<span style="font-family:SimSun;">// 此處的注釋,在各瀏覽器下,都能被作為注釋標簽正常識別 <! -- this is a comment --> </span>
- 注釋元素的關閉標簽”--“和">"之間允許有空白符。
- 應該避免在注釋內容中出現兩個或以上的”-“字符,否則可能出現錯誤。這個問題將導致頁面中的注釋部分在火狐的標準模式下被當做文本內容解析出來。
<span style="font-family:SimSun;"><!-- 這里是---注釋內容 --></span>
解決方案
按標準推薦的方法寫注釋標簽,如:
<!-- //此處 "<!" 和 "--" 之間盡量不要有空格。
這里是注釋內容,應避免在注釋內容中出現兩個或以上的“-”字符。
--> //此處 "--" 和 ">" 之間避免有空格。
不同瀏覽器對字符編碼別名支持的寬泛程度存在差異
根據規范,服務器應該提供給用戶端文檔的字符編碼信息,最直接的方式為通過http協議”Content-Type“頭字段的”charset“將文檔字符編碼告訴用戶端。
如:http頭聲明了字符編碼為UTF-8。
<span style="font-family:SimSun;"><pre name="code" class="javascript">Content-Type<span style="font-family: Arial, Helvetica, sans-serif;">="text/html;charset=UTF-8"</span></span>
處于某種情況無法訪問服務器時,html文檔可以包含有關文檔的字符編碼的明確信息,meta元素可以用來為用戶端提供這些信息,
<span style="font-family:SimSun;"><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></span>
當http協議和meta元素均沒有提供有關一個文檔的字符編碼信息時,html還為一些元素提供了charset屬性,
優先級:
- http”Content-Type“字段中的”charset“參數
- meta中的http-equiv="Content-Type"對應的”charset"值
- 元素的“charset”屬性
各瀏覽器中運行效果如下:
IE6 IE7 IE8 Firefox | Chrome Safari | Opera |
---|---|---|
字符編碼 --- GB2312 | ×Ö·û±àÂë --- ISO-8859-1 | 字符編碼 --- GBK |
解決方案:
首先,對于動態頁面必須確保 HTTP "Content-Type" 頭字段的 "charset" 參數與頁面自身編碼相符,且務必在頁面的 META 元素中也聲明相符的字符編碼信息。對于靜態頁面,必須保證頁面中
META 元素聲明中 "http-equiv" 為 "Content-Type" 對應的值中的 "charset" 的值與頁面自身編碼相符。
其次,在設置字符編碼別名時,最好使用最通用的、各瀏覽器均可識別的編碼別名。
DTD之前的非空字符在某些情況下會使該DTD失效
規范中提到,DTD的前面或后面允許出現空白符(空格符,換行符,制表符和注釋)。但是如果在DTD之前加入注釋或其他內容,在某些瀏覽中改DTD可能會無效。
- IE6 DTD 前的任何非空白符都將使瀏覽器忽略 DTD,包括注釋和 XML 聲明。
- IE7 IE8 DTD 前的任何非空白符都將使瀏覽器忽略 DTD,包括注釋,但不包括 XML 聲明。
- Firefox DTD 前的任何包含“<”的字符都將使瀏覽器忽略 DTD,但不包括 XML 聲明。
- Chrome Safari Opera DTD 前的任何非空白符都將使瀏覽器忽略 DTD,但不包括 XML 聲明。
一個 HTML 文檔的 DTD 前邊如果出現其他字符,在各瀏覽器中的處理情況是不一致的。
具體差異請參考下表:
如果 DTD 之前出現 | 瀏覽器是否能識別該 DTD | ||||||
---|---|---|---|---|---|---|---|
IE6 | IE7 | IE8 | Firefox | Chrome | Safari | Opera | |
空格符 換行符 制表符 | 可以識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 |
注釋1 | 不能識別 | 不能識別 | 不能識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 |
XML 聲明2 | 不能識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 | 可以識別 |
其他不包含“<”的字符3 | 不能識別 | 不能識別 | 不能識別 | 可以識別 | 不能識別 | 不能識別 | 不能識別 |
其他包含“<”的字符4 | 不能識別 | 不能識別 | 不能識別 | 不能識別 | 不能識別 | 不能識別 | 不能識別 |
【注】
1. 即HTML注釋,如 <!-- comment -->。
2. 類似 <?xml version="1.0" encoding="utf-8"?> 的 XML 聲明。
3. 即不是空格符、換行符、制表符,也不是注釋、XML 聲明的任何其他字符串,但不能包含“<”字符。
4. 即不是空格符、換行符、制表符,也不是注釋、XML 聲明的任何其他字符串,其中包含“<”字符。
通過以上對比可以看出,要保證 DTD 在所有瀏覽器中都能正常識別,DTD 之前只能出現空格符、換行符和制表符。
解決方案
聲明 DTD 時,確保 DTD 之前沒有其他字符,即便有,也只能是空格符、換行符和制表符。
如將 DTD 放在 HTML 文檔的第一行。
Chrome 和 Safari 中標簽緊密相鄰的行內元素在折行顯示時存在錯誤
這個問題是 WebKit 引擎在處理緊密相連的內聯元素時存在自動換行計算上的 Bug 。
針對此問題,我們使用以下測試樣例來說明,分析以下代碼:
<span style="font-family:SimSun;"><body> <a>[a]</a><span>[span]</span><strong>[strong]</strong><i>[i]</i><b>[b]</b><big>[big]</big><small>[small]</small><em>[em]</em><dfn>[dfn]</dfn><code>[code]</code><samp>[samp]</samp><kbd>[kbd]</kbd><var>[var]</var><cite>[cite]</cite><abbr>[abbr]</abbr><acronym>[acronym]</acronym><sub>[sub]</sub><sup>[sup]</sup><bdo>[bdo]</bdo> </body></span>
減小瀏覽器窗口尺寸后,在各瀏覽器中表現如下:
Chrome Safari | IE6 IE7 IE8 Firefox Opera |
---|---|
通過上圖比較可以發現,在非 WebKit 引擎的瀏覽器內,不管元素排列如何緊密,都可以隨著布局大小自動換行顯示; 而在 WebKit 引擎的瀏覽器中所有緊密相連的內聯元素都在同一行顯示,并且與文檔模式無關。
解決方案
避免出現緊密連接的內聯元素標簽,可以在每個標記之間加入空格或者換行符來避免這個問題。
Chrome 和 Safari 中 BR 元素前的空白符不會被忽略
W3C 規定 "ASCII 空格" 、 "ASCII 制表符" 、 "ASCII 換行符" 等屬于空白符(white space),對于多個連續的空白符,瀏覽器將對他們進行合并。
BR 元素會在當前行強制插入一個換行符,這個換行符也是空白符的一種。
Chrome 和 Safari 中 BR 元素前的空白符不會被忽略,多余的空白符將被壓縮為一個空白符并渲染到 BR 元素之前的行中。這個現象可能造成在 Chrome 和 Safari 中出現多余空白符占有位置,從而影響到容器的寬度或者行內元素的對齊效果。
<div style="zoom:1; overflow:hidden; margin-top:10px;">
<p style="text-align:right;">
<span style="background:#ddd;">A</span> <br /><span style="background:#eee;">B</span>
</p>
<p style="text-align:center;">
<span style="background:#ddd;">A</span> <br /><span style="background:#eee;">B</span>
</p>
<p style="text-align:left;">
<span style="background:#ddd;">A</span> <br /><span style="background:#eee;">B</span>
</p>
</div>
Chrome Safari 沒有忽略 BR 元素之前的空白符。而 其他瀏覽器 則將其忽略。
僅當容器的寬度不夠容納子元素時,Chrome Safari 才會忽略 BR 元素之前的空白符。
解決方案
刪除 BR 元素之前多余的空白符。
各瀏覽器下使用object元素和embed元素嵌入flash存在差異
object元素定義了一個嵌入的對象,通常情況下,IE系列通過ActiveX插件使用object元素引入flash,而其他瀏覽器則通過相應的插件使用embed元素。這就造成了各瀏覽器中插入flash的方式的差異。
若僅僅使用 OBJECT 元素設置了 classid 屬性引入 Flash,則可能造成在某些瀏覽器中 Flash 無法被引入。而若嵌套的 OBJECT 和 EMBED 元素參數不統一,也可能造成引入的 Flash 在各瀏覽器中出現差異。
通常我們會使用如結構代碼引入flash:
<object width="200" height="200" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#4,0,0,0">
<param name="src" value="clock.swf" />
<param name="quality" value="high" />
<embed src="clock.swf" type="application/x-shockwave-flash" width="200" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
</object>
將embed元素嵌套在object元素中,ie就會優先使用object元素而忽略embed元素,在其他瀏覽中則優先使用embed元素而忽略object元素。這樣做雖然可以保證在所有瀏覽器中均能正確加載flash,但若object元素和embed元素的參數設定不統一,則導致flash在各個瀏覽器中顯示效果不一致,甚至無法正常加載。
官方給出如下html中引用flash的情況。請參考 Adobe 官方知識庫文檔:OBJECT and EMBED syntax | Flash 與 Flash OBJECT and EMBED tag attributes中的內容。
<span style="font-family:SimSun;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400" id="movie_name" align="middle"> <param name="movie" value="movie_name.swf"/> <!--[if !IE]>--> <object type="application/x-shockwave-flash" data="movie_name.swf" width="550" height="400"> <param name="movie" value="movie_name.swf"/> <!--<![endif]--> <a href="http://www.adobe.com/go/getflash"> <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player"/> </a> <!--[if !IE]>--> </object> <!--<![endif]--> </object></span>
使用 EMBED 元素:flash_embed.html
<div style="border:5px solid black; padding:5px; float:left;">
<embed src="clock.swf" type="application/x-shockwave-flash" width="200" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
</div>
直接使用 EMBED 元素,所有瀏覽器均支持。
解決方案
- 若不考慮 W3C 校驗,可統一使用 EMBED 元素嵌入 Flash,這樣可以避免因參數不統一導致的兼容性問題。
- 若需要考慮 W3C 校驗(
Markup Validation Service),則可使用第三種單獨使用 OBJECT 與 PARAM 元素的方式。
- 若必須使用 OBJECT 嵌套 EMBED 元素這種混合方式,則要保證 Flash 文件 URL、為 Flash 傳遞的參數、寬度、高度、wmode 等參數保持統一。
- 可以使用開源的 SWFObject 引入 Flash。(請參見:
)
各瀏覽器對align="middle"的理解有差異
在規范中該屬性可以看到不同的align屬性,作用在不同的元素上,align屬性的意義也不同。
- object,img,applet:取值為“bottom,middle,top,left,right”這個屬性指定了它們與其上下文本的位置關系。
- table:取值為“center,left,right”,這個屬性指定了table元素在文檔中的位置。
- hr:取值為“center,left,right”,這個屬性指定了水平線在其上下文之間的水平對齊方式,默認為”center“。
- div,H1~H6,p:取值“center,left,right,justify”,指定了它們在其上下文環境內的水平對齊方式,默認為”left".
- col,colgroup,tbody,td,tfoot,th,thead,tr:“center,left,right,justify,char”,指定了單元格中數據及文本的對齊方式,對于td默認為“left”,對于th默認為“center”。
問題:
firefox,chrome,safari會將div,H1~H6 P元素的align=“middle”解析為align=“center”。從而使這些元素能夠居中對齊。
火狐混雜模式會將table元素align=“middle”解析為align=”center“,使table居中對齊。
IE6/7 ,chrome safari opera及ie8,firefox的混雜模式下,會將td,th元素的align=”middle“理解為align=”center“。
影響:
不正確使用align屬性的”middle“屬性值會在各瀏覽器中對應用元素的對齊方式產生差異,從而造成布局上的兼容性問題。
解決方案:
align="middle" 僅在 IMG、OBJECT、APPLET 元素上的 align 屬性中是合法值,對于其他元素的 align 屬性均為非法。各瀏覽器在上述三個元素之外的元素上遇到 align="middle" 均按照自己的理解方式解釋。同時除單元格元素的 align 屬性之外,其他的 align 屬性均被 W3C 官方廢棄(Deprecated.),所以應避免使用此屬性。
align="middle" 僅在 IMG、OBJECT、APPLET 元素上的 align 屬性中是合法值,對于其他元素的 align 屬性均為非法。各瀏覽器在上述三個元素之外的元素上遇到 align="middle" 均按照自己的理解方式解釋。同時除單元格元素的 align 屬性之外,其他的 align 屬性均被 W3C 官方廢棄(Deprecated.),所以應避免使用此屬性。
不能以size屬性精確控制input文本框或密碼框的寬度
問題:
字體的樣式會影響根據input元素的”size“屬性計算的文本框寬度,其中包括”font-family","font-size","font-syle","letter-spacing".若僅僅為input元素設置“size”屬性,卻沒有顯式地設定寬度,則在不同的瀏覽器中input元素會出現不同的寬度。
解決方案:
不要試圖通過設置 "size" 屬性使 INPUT[type=text/password] 元素在所有瀏覽器中的寬度一致,這是不可能的。在需要對這類元素做精確的控制時,應使用 CSS 的 'width' 和 'height' 特性。
另外不同瀏覽器的默認字體的區別會導致文本框內文字表現的差異,最好為 INPUT 元素顯式設置字體樣式覆蓋其默認值,以保證文本框在所有瀏覽器中有相同的呈現效果。
各瀏覽器中密碼框掩碼的外觀不完全一致
W3C沒有規定用戶端用于隱藏用戶實際輸入文本的“掩碼”的文字編碼和相關字體特性。
問題:
密碼框中的掩碼用來覆蓋密碼明文,它沒有相應規范指定統一顯示樣式,因此導致不同系統與不同瀏覽器中密碼框“input[type="password"]的掩碼字符均有很大的差異。可幸的是,這種差異只會在視覺上產生不同,而不會造成布局上的差異。
檢查瀏覽器對于 input[type=password] 標記的相關默認字體樣式設置:
匯總后得到如下字體樣式的差異表:
IE6 IE8 IE8(EmulateIE7) | IE7 Firefox | Safari | Chrome | Opera | |
---|---|---|---|---|---|
font-family | Tahoma | SimSun | SimSun | Arial | 宋體 |
font-weight | 400 | 400 | normal | normal | 400 |
font-size | 13px | 13px | 13px | 13px | 13px |
可見各瀏覽器中 'font-weight' 及 'font-size' 定義沒有差異。
查看掩碼字符,過濾的眾多可疑的圓點字符后,總結出下表:
IE7 Firefox | IE6 IE8 Chrome Safari | Opera | |
---|---|---|---|
TEXT-UNICODE | 0x25cf | 0x2022 | 0x002a |
將上下兩表結合,重現各瀏覽中掩碼字符的默認樣式如下:
IE6 IE8 IE8(EmulateIE7) | IE7 Firefox | Safari | Chrome | Opera | |
---|---|---|---|---|---|
font-family | Tahoma | SimSun | SimSun | Arial | 宋體 |
font-weight | 400 | 400 | normal | normal | 400 |
font-size | 13px | 13px | 13px | 13px | 13px |
TEXT-UNICODE | 0x2022 | 0x25cf | 0x2022 | 0x2022 | 0x002a |
顯示效果 | ●●● | ●●● | ••• | ••• | *** |
解決方案:
由于掩碼字符無法被修改,因此僅通過 CSS 統一密碼輸入框的掩碼樣式是不可能的。且這種差異可以忽略不計。
這里給出兩種解決思路:
- 通過 CSS hack 方式對不同的瀏覽器設置不同的字體和字號,除去 Opera 外,可以減小掩碼樣式的差異。
- 或者使用 JavaScript 對普通的文本輸入框做輸入監聽編程,用自定義掩碼字符填充輸入框來制做自定義密碼輸入框效果。
firefox opera中object元素的默認尺寸為不可視
規范中對object元素的渲染規則:
- 用戶端先必須嘗試渲染object,而不應該渲染其內容,但在其內部包含param一級子元素時必須對它們進行檢查。
- 若用戶端出于某種原因無法渲染object,則必須嘗試渲染其內容。
問題:
firefox opera中object元素的默認尺寸為不可視,而IE中,object默認尺寸為16*16PX,在chrome和safari中默認尺寸為300*150px。
也就是說,如果沒有為object元素設置明確的寬度和高度,則可能在各瀏覽器中由于其內在尺寸不同導致最終布局上的差異。
解決方案:
OBJECT 元素為替換元素,應為 OBJECT 元素設置一個明確的寬度和高度。
Firefox 中 TEXTAREA 元素根據 'rows' 設置值生成的實際行數為設置值 + 1
解決方案:
當我們僅僅為 TEXTAREA 元素設置 "rows" 屬性以控制其高度時,在 Firefox 中無法得到我們預期的效果。且其他瀏覽器對 "rows" 屬性設置的元素高度也不盡相同,這一點 W3C 沒有明確規范 "rows" 屬性計算高度時的具體算法。
如果要精確控制 TEXTAREA 元素的尺寸(高度)時,請避免使用 "rows" 屬性改用 CSS 相關設定,以保證所有瀏覽器擁有統一的視覺樣式。
文章列表