摘要:本節內容會跟著上一節的內容繼續完善,首先會補充選擇器的瀏覽器支持情況主要是說,比如我們最常用的群組選擇器在時才被支持,并且還支持了很多我們沒有想到的選擇器,如子元素選擇器,屬性選擇器,了解后你會發現還是挺了不起的。
前言
上一篇系列文章整理了CSS選擇器的基礎使用方法,因為內容較多且細致,寫了很多DEMO,目前將它整理成適合移動端瀏覽器的CSS選擇器的參考手冊,方便學習CSS的人參考使用,馬上就要搞定了,之后會放出 (笑臉)。
本節內容會跟著上一節的內容繼續完善,首先會補充CSS選擇器的瀏覽器支持情況(主要是說IE),比如我們最常用的s1,s2,…,sN群組選擇器在IE7時才被支持,并且IE7還支持了很多我們沒有想到的選擇器,如子元素選擇器,屬性選擇器,了解后你會發現IE7還是挺了不起的。
之后還會補充平常使用選擇器遇到的一些問題以及解決方案,最后了解瀏覽器是如何讀取選擇器的,怎樣使用選擇器能達到高效率。
瀏覽器支持 了不起的IE7當我們在開發網頁時,如果網頁需要兼容IE6,那么自然地會把IE6和IE7瀏覽器歸為一路貨色,對于不兼容的選擇器和屬性都將不再考慮使用,可是你是否知道IE7相比IE6增加了許多選擇器可以用,如群組選擇器,相鄰選擇器,兄弟選擇器,屬性選擇器。
以下選擇器是不支持IE6,僅支持 IE7 及以上的瀏覽器
基本選擇器選擇器 | 描述 | 版本 |
---|---|---|
s1,s2,...,sN | 群組選擇器,同時匹配所有s1元素或s2元素 | 2.1 |
E > F | 子元素選擇器,匹配所有E元素的子元素F | 2.1 |
E + F | 毗鄰元素選擇器,匹配所有緊隨E元素之后的同級元素F | 2.1 |
E ~ F | 匹配任何E標簽之后的同級F標簽 | 3 |
選擇器 | 描述 | 版本 |
---|---|---|
E[attr] | 匹配att屬性的E元素 | 2.1 |
E[attr="val"] | 匹配att屬性且屬性值等于val的E元素 | 2.1 |
E[attr~="val"] | 匹配att屬性且屬性值中的詞列表有一個等于val的E元素 | 2.1 |
E[attr^="val"] | 匹配att屬性且屬性值為以val開頭的字符串的E元素 | 3 |
E[attr$="val"] | 匹配att屬性且屬性值為以val結尾的字符串的E元素 | 3 |
E[attr*="val"] | 匹配att屬性且屬性值為包含val的字符串的E元素 | 3 |
E[att|="val"] | 匹配att屬性且屬性值為以val開頭并用連接符"-"分隔的字符串的E元素 | 2.1 |
在IE7瀏覽器,單復選框的checked在屬性選擇器中是不被支持的,這部分內容會在下面的常見問題中詳細說明。
偽類選擇器選擇器 | 描述 | 版本 |
---|---|---|
E:hover | 設置元素在其鼠標懸停時的樣式 | 2.1 |
E:first-child | 匹配父元素的第一個子元素E | 2.1 |
E:hover在IE6中只有a元素可用
偽元素選擇器選擇器 | 描述 | 版本 |
---|---|---|
E:first-letter | 選擇文本塊的第一個字母 | 2.1 |
E:first-line | 選擇元素的第一行 | 2.1 |
雖然來到IE8的時代,但是對于新選擇器的支持并不多,不過還好我們最常用的E:before和E:after配合content屬性都在IE8中得到了很好的支持。
以下選擇器不支持IE6,IE7,僅支持 IE8 及以上的瀏覽器
偽類選擇器選擇器 | 描述 | 版本 |
---|---|---|
E:focus | 設置對象在成為輸入焦點時的樣式 | 2.1 |
選擇器 | 描述 | 版本 |
---|---|---|
E:before | 在元素前面插入內容,配合"content"使用 | 2.1 |
E:after | 在元素后面插入內容,配合"content"使用 | 2.1 |
IE最好的時代就是迎接CSS3的到來,從IE9支持了一大坨新CSS3的偽類以及偽元素,我就勉強給IE使用上這個酷炫點的修飾語。
以下選擇器不支持IE6,IE7,IE8,僅支持 IE9 及以上的瀏覽器
偽類選擇器選擇器 | 描述 | 版本 |
---|---|---|
E:checked | 匹配用戶界面上處于選中狀態的元素E | 3 |
E:enabled | 匹配用戶界面上處于可用狀態的元素E | 3 |
E:disabled | 匹配用戶界面上處于禁用狀態的元素E | 3 |
E:root | 匹配文檔的根元素,對于HTML文檔,就是HTML元素 | 3 |
E:last-child | 匹配父元素的最后一個子元素E | 3 |
E:nth-last-child(n) | 匹配父元素的倒數第n個子元素E | 3 |
E:nth-of-type(n) | 匹配同類型中的第n個同級兄弟元素E | 3 |
E:nth-last-of-type(n) | 匹配同類型中的倒數第n個同級兄弟元素E | 3 |
E:first-of-type | 匹配同類型中的第一個同級兄弟元素E | 3 |
E:last-of-type | 匹配同類型中的最后一個同級兄弟元素E | 3 |
E:only-child | 匹配父元素僅有的一個子元素E | 3 |
E:only-of-type | 匹配同類型中的唯一的一個同級兄弟元素E | 3 |
E:empty | 匹配沒有任何子元素(包括text節點)的元素E | 3 |
E:not(s) | 匹配不含有s選擇符的元素 | 3 |
E:target | 匹配文檔中特定"id"點擊后的效果 | 3 |
選擇器 | 描述 | 版本 |
---|---|---|
E::first-letter | 選擇文本塊的第一個字母 | 3 |
E::first-line | 選擇元素的第一行 | 3 |
E::before | 在元素前面插入內容,配合"content"使用 | 3 |
E::after | 在元素后面插入內容,配合"content"使用 | 3 |
E::selection | 設置對象被選擇時的樣式 | 3 |
如何才能讓IE6~8支持CSS3偽類和屬性選擇器,也許你已經想到了,我們會用JavaScript工具來進行輔助,那么剛好|8e50989464f7517425e2c31ba2d6dd59424|就可以完成這件事情,而且使用起來很簡單,只要把selectivizr.js引入到頁面上就可以了,如下:
但是使用它還有一些注意事項:
必須要引用一個JavaScript庫,比如jQuery
只能解析標簽引入的樣式,如果是定義的樣式是不會解析的
動態生成的DOM不會做二次映射
需要在標準模式的DTD才能夠生效
項目地址:http://selectivizr.com
常見問題與Bug * 通配符造成繼承失效* { color:red; } #test{ color:blue; }
▲ 最終text的顏色卻是紅色的
按照我們的理解,id的優先級是高于*通配符的,而文字也本應該繼承id元素的color值,所以最終的文字應該是藍色呀。
所以這里混淆了一個概念,繼承的樣式的優先級永遠低于元素本身的樣式,包括通配符選擇器,所以大家在開發中,應該盡可能的避免濫用通配符,以免帶來一些隱性問題。
關于這個問題,還可以參考《關于CSS特殊性的問題》
而在IE6及更早瀏覽器并不支持通配選擇符(*),只是將它忽略了,所以也變相的能看到效果。
E:hover 失效E:hover偽類用于設置元素在其鼠標懸停時的樣式,但是在某種情況會導致效果失效,如下:
#test { background:red; } #test div { display:none; } #test:hover div{ display:block; background:yellow; }
觸發我看到我了吧
▲ 當觸發#test:hover時,此效果是在IE6中是無效的,因為在IE6中,E:hover偽類僅能用于a(超鏈接)對象,且該a對象必須要擁有href屬性。
E:hover還有一種失效的狀態,是大家最常見的,代碼如下:
a:link {color:gray;} a:hover{color:green;} a:visited{color:yellow;} a:active{color:blue;}
文字
▲ 當超鏈接處于a:hover時,你會發現其效果是無效,文字的顏色不會變成綠色,這是因為超鏈接的偽類樣式書寫是有固定順序的,不能顛倒,這四個屬性正確的定義順序為:
a:link {} a:visited {} a:hover {} a:active {}E:focus 失效
#test:focus + p { font-weight:bold; }
文字
▲ 當點擊button按鈕觸發:focus時將鄰近元素的文字進行加粗,但是這個效果在IE8是失效的,如何來修復它呢,只需要添加一個空的:focus選擇器,如下:
#test:focus + p { font-weight:bold; } #test:focus {}E:first-line 失效
如果在當前選擇器內使用了!important,:first-line偽類內部的定義的屬性會被完全忽略,示例:
p { color:blue; } p:first-line { color:red !important; }
第一行文字,
第二行文字
▲ 正常情況下第一行的文字會變成紅色,但是在IE8瀏覽器卻忽略它沒有任何變化,如何來解決這個問題呢,把!important去掉就好了,如下:。
p { color:blue; } p:first-line { color:red; }E:first-letter 失效
E:first-letter失效和E:first-line失效的問題是相同的,解決方案請參考上方。
E > F 失效就是子選擇器中間有注釋會導致屬性失效,如下:
#test > /*子選擇器*/ p { color:red; }
文字
▲ 如果你非要這樣寫注釋,那么在IE7下會導致子選擇器失效,同樣,E + F鄰近選擇器也有同樣的問題,如何解決呢,不在選擇器中間添加注釋就可以了。
性能優化CSS 選擇器我們都在使用,但是如何讓它變的更簡潔,高效呢?
首先選擇器對性能的影響源于瀏覽器匹配選擇器和文檔元素時所消耗的時間,所以優化選擇器的原則是應盡量避免使用消耗更多匹配時間的選擇器,但是在此之前我們需要先了解瀏覽器的匹配機制,就是它是如何讀取我們的選擇器的。
#nav > a { color:red; }
當我們看到這個選擇器的時候,會認為首先會找到id為nav的元素,然后在找到其子元素,將樣式屬性應用到a元素上。
事實上,卻恰恰相反,因為瀏覽器讀取選擇器時,不是按照我們的閱讀習慣從左到右,而是遵循的從選擇器的右邊到左邊進行讀取的。
當我們知道這個匹配機制后,再回來看這個選擇器,瀏覽器必須先遍歷頁面中所有的 a 元素,然后查找其父元素的id是否為nav,這樣一來你就會發看似高效的選擇器在實際中的匹配開銷是很高的。
理解了CSS選擇器從右到左匹配的機制后,我們再看以下兩種選擇器:
div #nav
#nav div
你是否會認為第2種選擇器的效率要高于第1種,那么就錯了,其實第一個選擇器的效率更高,因為第一個選擇器的關鍵選擇器使用了#id選擇器”,而第二個選擇器的關鍵選擇器使用的是div標簽選擇器。
這里所說的關鍵選擇器,就是CSS選擇器中最右邊部分,它是被瀏覽器最先尋找的,那么哪類選擇器是最高效的?哪個是會影響選擇器效率的關鍵選擇器?
選擇器效率在上面內容中我們了解瀏覽器的匹配機制,以及關鍵選擇器的重要性,那么哪些CSS選擇器能夠減少性能損耗呢?
Google 資深web開發工程師 Steve Souders 對 CSS 選擇器的執行效率從高到低做了一個排序:
id選擇器(#id)
類選擇器(.className)
標簽選擇器(div,h1,p)
相鄰選擇器(h1+p)
子選擇器(ul > li)
后代選擇器(li a)
通配符選擇器(*)
屬性選擇器(a[rel="external"])
偽類選擇器(a:hover,li:nth-child)
從Steve Souders的CSS Test我們可以看出#id選擇器和.className類選擇器在速度上的差異很小很小。而在一個a標簽選擇器的測試上顯示,它比#id選擇器和類選擇器的速度慢了很多,從這里我們可以看出#id、.className選擇器 和 a標簽、li a后代選擇器中間的差異較大,但是相互之間的差異較小。
接下來舉幾個示例:
#nav {} .menu{}
p#nav {} p.menu {}
▲ 上面的選擇器效率要高于下面的選擇器,標簽元素會降低選擇器效率
優化建議我們理解了CSS選擇器從右到左匹配的機制,也了解關鍵選擇器的重要性,以及CSS選擇器的效率排序,那么在使用選擇器的時候,通過避免不恰當的使用,來提升 CSS 選擇器性能。
避免使用通用選擇器#nav * {…}
▲ 這個選擇器所做的是選擇所有在頁面上的單個元素(是每個單個的元素),然后去看看它們是否有一個#nav的父元素。這是非常不高效選擇器,開銷太大了,應該避免關鍵選擇器是通配選擇器的情況。
避免使用標簽或 class 選擇器限制 id 選擇器/* Bad */ div#nav {…} .menuBalck#menu {…} /* Good */ #nav {…} #menu {…}
▲ ID選擇器本身就是唯一的,加上div反而增加不必要的匹配;
避免使用標簽限制 class 選擇器/* Bad */ span.red {…} /* Good */ .text-red {…}
▲ 在標簽上定義class選擇器,在開發和維護時容易混淆,一般不建議這樣寫。
避免使用多層標簽選擇器。使用 class 選擇器替換,減少css查找/* Bad */ a[href="#"] > span > em {…} /* Good */ .className {}
▲ 這種情況建議直接定義.className 選擇器,然后使用
避免過渡使用子選擇器/* Bad */ div ul li a {} div > ul > li > a {} /* Good */ .className {…}
▲ 這種情況建議直接定義.className 選擇器,然后使用
避免過度限制選擇器/* Bad */ html body .wrapper #content a {} /* Good */ #content a {}
▲ 這里至少有3個選擇器是完全不需要的,過度限制選擇器使瀏覽器工作比它實際需要的更繁重,花費的時間更多,所以這里應該避免。
利用可繼承性/* Bad */ #nav > li > a { color:red; } /* Good */ #nav { color:red; }
▲ 在使用選擇器之前,請先考慮利用繼承性實現
下一節繼續整理選擇器的優先級和繼承性相關內容。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111132.html
摘要:從現在開始,養成寫技術博客的習慣,或許可以在你的職業生涯發揮著不可忽略的作用。如果想了解更多優秀的前端資料,建議收藏下前端英文網站匯總這個網站,收錄了國外一些優質的博客及其視頻資料。 前言 寫文章是一個短期收益少,長期收益很大的一件事情,人們總是高估短期收益,低估長期收益。往往是很多人堅持不下來,特別是寫文章的初期,剛寫完文章沒有人閱讀會有一種挫敗感,影響了后期創作。 從某種意義上說,...
摘要:任務五一個最常見的移動端頁面完成的事情學習張鑫旭世界相關章節張鑫旭系列了解通配符選擇器性能優化瀏覽器渲染原理學習各屬性及效果完成任務五學習編碼規范編碼規范并按照編碼規范優化代碼完成深度思考計劃的事情找時間把前面任務的官方提供鏈接過一遍,查缺 任務五、 一個最常見的移動端頁面 完成的事情 float學習 張鑫旭《CSS世界》相關章節 張鑫旭 float系列 了解CSS通配符 &...
閱讀 2209·2021-09-30 09:47
閱讀 959·2021-08-27 13:01
閱讀 2959·2019-08-30 15:54
閱讀 3685·2019-08-30 15:53
閱讀 825·2019-08-29 14:07
閱讀 711·2019-08-28 18:16
閱讀 795·2019-08-26 18:37
閱讀 1406·2019-08-26 13:27