本篇介紹了CSS3與頁面佈局學習總結-瀏覽器相容與前端效能優化,具體如下:
一、瀏覽器相容
#1.1、概要
世界上沒有任何一個瀏覽器是一樣的,同樣的程式碼在不一樣的瀏覽器上運作就存在相容性問題。不同瀏覽器其核心亦不盡相同,相同核心的版本不同,相同版本的核心瀏覽器品牌不一樣,各種運作平台仍有差異、螢幕解析度不一樣,大小不一樣,比例不一樣。相容性主要考慮三方面:
1)、CSS相容
2)、JavaScript相容
3)、HTML相容
這三類也是前端的主要組成部分,都存在一定的相容性問題,知己知彼,百戰百勝,我們先了解瀏覽器的引擎—核心。
多年前我們一直為IE6兼容煩惱,為它沒少加班;盼走了IE6現在又出現了IE8,看來兼容沒有盡頭...
1.2、瀏覽器內核
Trident
Microsoft公司瀏覽器內核,IE6、IE7、IE8(Trident 4.0)、 IE9(Trident 5.0)、IE10(Trident 6.0)及許多品牌瀏覽器的核心。其中部分瀏覽器的新版本是“雙核心”甚至是“多核心”,其中一個核心是Trident,然後再增加一個其他核心。
Gecko
Firefox內核,Netscape6開始採用的內核,後來的Mozilla FireFox(火狐瀏覽器) ,Mozilla Firefox、Mozilla SeaMonkey、waterfox(Firefox的64位元開源版)、Iceweasel、Epiphany(早期版本)、Flock(早期版本)、K-Meleon所使用的核心。
Presto
Opera前內核,已被放棄,Opera現已改用Google Chrome的Blink內核。
Webkit
Safari內核,Chrome內核原型,開源,它是蘋果公司自己的內核,也是蘋果的Safari瀏覽器使用的核心。 傲遊瀏覽器3、Apple Safari、(Win/Mac/iPhone/iPad)、Symbian手機瀏覽器、Android 預設瀏覽器
Blink
Blink是一個由Google和Opera Software開發的瀏覽器排版引擎,Google計畫將這個渲染引擎作為Chromium計畫的一部分,這個渲染引擎是開源引擎WebKit中WebCore元件的一個分支,並且在Chrome(28及往後版本)、Opera (15及往後版本)。
edge
微軟專門為新IE打造的引擎,速度快,目前已經基於此引擎開發了瀏覽器,目前IE11使用該內核,估計以後微軟的新瀏覽器會繼續採用該核心。
1.3、瀏覽器市場份額(Browser Market Share)
能過瀏覽器的市佔率我們可以在處理瀏覽器相容性時會更加關注市場份額高的瀏覽器,適當的時候可以放棄市場佔有率佔有量小的瀏覽器。
國際:
查詢網址:http://tongji.baidu.com/data/browser
2016年12月PC瀏覽器資料
2016年12月平板+行動資料
2016瀏覽器份額變更
#國內:
查詢網址:http://browsershots.org/
################ #####從上圖可以看出,我們在針對PC Web開發時需要專注於Chrome、IE瀏覽器,開發Mobile專案時要專注於Chrome瀏覽器與Safari。 ###1.4、相容的一般標準
1)、在不同的主流的瀏覽器上表現效果一致
2)、能適應不同的螢幕大小
3)、能適應不同的解析度與色彩深度
瀏覽器相容線上測試:
http://browsershots.org/
#IE測試可以安裝:IETester在本機測試。
1.5、CSS Reset
每個瀏覽器都有一套預設的樣式表,即user agent stylesheet,網頁在沒有指定的樣式時,請按瀏覽器內建的樣式表渲染。這是合理的,像word中也有一些預留樣式,可以讓我們的排版更美觀整齊。不同瀏覽器甚至同一瀏覽器不同版本的預設樣式是不同的。但這會有很多相容問題,CSSReset可以將所有瀏覽器預設樣式設定成一樣。
如全域重置*{ padding: 0; margin: 0; border:}雖然能全部重置,但由於效能較低,不建議使用。因為*需要遍歷整個DOM樹,當頁面節點較多時,會影響頁面的渲染效能。這個網站http://cssreset.com/有最新的CSSReset提供給大家參考。
Normalize (號稱是CSS reset的替代方案,保留了一些內建的樣式,並不是清除所有)
http://nicolasgallagher.com /about-normalize-css/
https://github.com/necolas/normalize.css
範例:請看第2章的內容
# 1.6、CSS Hack
CSS Hack就是針對不同的瀏覽器或不同版本瀏覽器寫特定的CSS樣式達到讓瀏覽器相容的過程。
1.6.1、條件註解法
IE條件註解(Conditional comments)是IE瀏覽器私有的程式碼,在其它瀏覽器中被視為註解。
gt : greater than,選擇條件版本以上版本,不包含條件版本>
lt : less than,選擇條件版本以下版本,不包含條件版本
#gte : greater than or equal,選擇條件版本以上版本,包含條件版本>=
lte : less than or equal,選擇條件版本以下版本,包含條件版本
#! : 選擇條件版本以外所有版本,無論高低
*只有IE瀏覽器認識條件註解、其它瀏覽器會跳過
範例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <!--[if gt IE 6]> <style> body{ background:lightblue; } </style> <![endif]--> <!--[if lt IE 8]> <script type="text/javascript"> alert("您的浏览器Out了,请下载更新。"); </script> <![endif]--> </head> <body> <!--[if gt IE 6]> <h2>大于IE6版本的浏览器</h2> <![endif]--> </body> </html>
效果:
IE8
#chrome
# #ie6
1.6.2、樣式內屬性標記法
在CSS樣式的屬性名稱前或值後面加上特殊的字元讓不同的瀏覽器解析。 #########http://browserhacks.com/線上查詢, 這個功能強大的提供各種針對性相容辦法的網站,非常實用。 ###############「-″底線是IE6專有的hack######「\9″ IE6/IE7/IE8/IE9/IE10都生效#### ##「\0″ IE8/IE9/IE10都生效,是IE8/9/10的hack######「\9\0″ 只對IE9/IE10生效,是IE9/10的hack### ###這裡以IE6雙邊距問題為例。 ######程式碼:#########<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #p1{ width: 100px; height: 100px; background: lightgreen; float: left; margin-left: 100px; _margin-left: 50px; } </style> </head> <body> <p id="p1"></p> </body> </html>
1.6.3、选择器前缀法
*html *前缀只对IE6生效
*+html *+前缀只对IE7生效
@media screen\9{...}只对IE6/7生效
@media \0screen {body { background: red; }}只对IE8有效
@media \0screen\,screen\9{body { background: blue; }}只对IE6/7/8有效
@media screen\0 {body { background: green; }} 只对IE8/9/10有效
@media screen and (min-width:0\0) {body { background: gray; }} 只对IE9/10有效
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {body { background: orange; }} 只对IE10有效
《hack速查表》:
<!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>hack速查表</title> <style type="text/css"> /*reset*/ * { margin: 0; padding: 0; } body { font: normal 12px/2 Tahoma, Arial, "\5b8b\4f53", Helvetica, sans-serif; height: 100%; text-align: center; background: #fff; } h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; } /* Tables still need 'cellspacing="0"' in the markup. */ table { border-collapse: collapse; border-spacing: 0; } ul, ol { list-style: none; } em { font-style: normal; color: #f00; } h1 { font-size: 2em; font-weight: 700; } .hack { width: 1000px; margin: 0 auto; text-align: left; } .hack table { width: 100%; margin: 10px 0; } .hack td, .hack th { height: 30px; padding: 0 5px; border: 1px solid #ccc; } .hack th { color: #cc0bf6; } .hack th.eq, .hack td.eq { width: 350px; color: #333; } .hack th.identifier, .hack td.hack-data { width: 350px; color: #61602f; } .hack td.no { color: #fff; text-align: center; background-color: red; } .hack td.yes { color: #fff; text-align: center; background-color: green; } .hack p b { color: green; } .hack p b.red { color: red; } .hack h2 { margin: 10px 0 0 0; font-size: 1.5em; font-weight: 700; } .hack-list { margin: 10px 0; } .hack-list li { margin-bottom: 5px; zoom: 1; } .hack-list span { float: left; width: 15px; font-family: "\5b8b\4f53"; } .hack-list-inf { padding: 0 0 0 15px; } .hack-list em { display: inline-block; margin: 0 5px; } </style> </head> <body> <h1>hack速查表</h1> <p class="hack"> <p>建议:以标准浏览器为准书写代码,如遇到兼容问题,尝试其他方法解决问题,在万不得已怕情况下,采用HACK解决。</p> <p>以下是我总结的HACK书写方法:</p> <p>浏览器:仅限IE6+,FF,safari,chrome,opera;(截止到2011.10.12非IE均为最新版本)。</p> <p>测试环境:windows系统;</p> <p>DOCTYPE: <!doctype html>.</p> <table cellpadding="0"> <thead> <tr> <th class="identifier">标志符</th> <th class="eq">示例</th> <th>IE6</th> <th>IE7</th> <th>IE8</th> <th>IE9</th> <th>FF</th> <th>OP</th> <th>SA</th> <th>CH</th> </tr> </thead> <tbody> <tr> <td class="hack-data">*</td> <td>.eq {*color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">_</td> <td>.eq {_color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">+</td> <td>.eq {+color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">-</td> <td>.eq {-color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">></td> <td>.eq {>color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">\0</td> <td>.eq {color:#000\0;}</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">\9</td> <td>.eq {color:#000\9;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">\9\0</td> <td>.eq {color:#000\0;}</td> <td class="no">N</td> <td class="no">N</td> <td>N\Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">:root .xx{xxx:xxx\9;}</td> <td>:root .eq {color:#a00\9;}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*+</td> <td>.eq {*+color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*-</td> <td>.eq {*-color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*html</td> <td><span class="hack-data">*html</span> .eq {color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*+html</td> <td><span class="hack-data">*+html</span> .eq {color:#000;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">html*</td> <td>html* .eq {color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">[;</td> <td>.eq {color:red;[;color:blue;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">html>body</td> <td>html>body .eq {color:blue;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">html>/**/body</td> <td>html>/**/body .eq {color:blue;}</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">html/**/>body</td> <td>html/**/>body .eq {color:blue;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">@media all and (min-width:0px){}</td> <td><span class="hack-data">@media all and (min-width:0px){.eq {color:#000;}}</span></td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">*:first-child+html</td> <td>*:first-child+html .eq {color:blue;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*:first-child+html{} *html</td> <td>*:first-child+html{} *html .eq {color:blue;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">@-moz-document url-prefix(){}</td> <td>@-moz-document url-prefix(){ .eq {color:blue;}}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">@media screen and (-webkit-min-device-pixel-ratio:0){}</td> <td>@media screen and (-webkit-min-device-pixel-ratio:0){.eq {color:blue;}}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){}</td> <td><span class="hack-data">@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){.eq {color:blue;}}</span></td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">body:nth-of-type(1)</td> <td>body:nth-of-type(1) .eq {color:blue;}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> </tbody> <tfoot> <tr> <th class="identifier">标志符</th> <th class="eq">示例</th> <th>IE6</th> <th>IE7</th> <th>IE8</th> <th>IE9</th> <th>FF</th> <th>OP</th> <th>SA</th> <th>CH</th> </tr> </tfoot> </table> <p>FF:firefox; OP:opera; SA:safari; CH:chrome; <b>Y</b>代表支持,<b class="red">N</b>代表不支持。</p> <h2>注意事项:</h2> <ul class="hack-list"> <li><span>·</span> <p class="hack-list-inf">由于各浏览器更新神速,所以有些HACK可能会有变化,所以请大家注意。</p> </li> <li><span>·</span> <p class="hack-list-inf"><em>[;</em>此种方式会影响后续样式,不可取。</p> </li> <li><span>·</span> <p class="hack-list-inf"><em>\9\0</em>并非对所有属性都能区分IE8和IE9.比如:background-color可以,但background不可以,还有border也不可以。所以在实际用时要测试下。</p> </li> <li><span>·</span> <p class="hack-list-inf">当同时出现<em>\0</em>;<em>*</em>;<em>_</em>;时,推荐将\0写在*和_前面。例如:color:red\0;*color:blue;_color:green;可行,否则IE7和IE6里的效果会失效。但border例外,放在前后都可以。保险起见,还是放在前面。 </p> </li> </ul> <h2>推荐写法:</h2> <h3>demo:</h3> <pre class="brush:php;toolbar:false"> .eq { color:#f00;/*标准浏览器*/ color:#f30\0;/*IE8,IE9,opera*/ *color:#c00;/*IE7及IE6*/ _color:#600;/*IE6专属*/ } :root .eq {color:#a00\9;}/*IE9专属*/ @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){.eq {color:#450;}}/*opera专属*/ @media screen and (-webkit-min-device-pixel-ratio:0){.eq {color:#879;}}/*webkit专属*/ @-moz-document url-prefix(){ .eq {color:#4dd;}}/*firefox专属*/
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> @media screen\0 { body { background: lightblue; } } </style> </head> <body> </body> </html>
运行结果:
1.7、文档模式 (X-UA-Compatible)
文档模式是IE8浏览器以后的一种独有技术,他可以通过meta指定当前文档的渲染模式,如可以把IE8降级成IE6、IE7使用。文档模式的主要作用是影响浏览器显示网页HTML的方式,用于指定IE的页面排版引擎(Trident)以哪个版本的方式来解析并渲染网页代码。
<meta http-equiv="X-UA-Compatible" content="IE=6" > <meta http-equiv="X-UA-Compatible" content="IE=7" > <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" > <meta http-equiv="X-UA-Compatible" content="IE=edge" >//最新IE
“X-UA-Compatible”的值有两种方式:Emulate+IE版本号,单纯版本号
EmulateIE8:如果声明了文档类型,则以IE8标准模式渲染页面,否则将文档模式设置为IE5
9:强制以IE9标准模式渲染页面,忽略文档类型声明
x-ua-compatible 头标签大小写不敏感,必须用在 head 中,必须在除 title 外的其他 meta 之前使用。
<meta http-equiv="x-ua-compatible" content="IE=7,9,10" > <meta http-equiv ="X-UA-Compatible" content = "IE=edge,chrome=1" />
Google Chrome Frame(谷歌内嵌浏览器框架GCF)
插件可以让用户的IE浏览器外不变,但用户在浏览网页时,实际上使用的是Google Chrome浏览器内核
未指定文档模式时使用默认的文档模式示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>X-UA-Compatible</title> <style> #p1 { width: 100px; height: 100px; background: lightgreen; float: left; margin-left: 100px; _margin-left: 50px; } </style> </head> <body> <p id="p1"></p> </body> </html>
运行结果:
强制指定文档模式为IE6,在IE8下会自动变成怪异模式,简单说IE8被当作IE6在用。
多数情况下我们不会这样降级使用,一般会将IE选择为最新版本的文档模式(注意不是文档类型),如果IE浏览器使用了GCF技术我们应该强制使用最新版内核,写入如下:
现在多数网站这是这种写法如baidu。
1.8、javascript兼容
这里有两层意思,第一可以使用javascript操作样式与标签,强制浏览器兼容,比如先使用javascript判断浏览器类型,再操作样式与标签。
第二指javascript存在兼容问题,如一个对象在某些浏览器下没有办法使用,要让javascript更加兼容,可以采取如下办法:
1、使用第三方提代的javascript库,如jQuery,Zepto, Prototype,dojo、YUI、ExtJS
像jQuery这种成熟的javascript库经过多次的版本迭代,已经变得非常成熟,世界上的网站到现在近60%都使用到了jQuery,他的兼容性不错。
2、浏览器检测、重新封装
使用javascript判断浏览器类型,对一些特点的方法或对象重新封装后使用屏蔽浏览的不兼容性。可以使用User-Agent、或特定对象。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h2 id="msg"></h2> <script type="text/javascript"> //用于检测浏览器是否为IE var isIE=function(){ return !!window.ActiveXObject; } function show(info){ document.getElementById("msg").innerHTML+=info+"<br/>" } //获得用户代理对象,浏览器与操作系统信息 show(navigator.userAgent); show(isIE()?"是IE浏览器":"不是IE浏览器"); </script> </body> </html>
效果:
在user-agent中包含有不少的客户端信息,可以解析出判断浏览器部分的内容。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。
更多CSS3瀏覽器相容相关文章请关注PHP中文网!