生活随笔
收集整理的這篇文章主要介紹了
CSS选择器的权重详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在我們開始之前,先搞明白幾個概念吧。下面是一段CSS代碼:
| ??outline: 1px dotted #eee; |
| ??background-image: url(http://static.jquery.com/files/rocker/images/bg-interior-tile-drk.jpg); |
上面這個樣式表是由一個個樣式規則組成,而每一個樣式規則又可以分為兩部分:選擇符與聲明。選擇符就相當于jQuery的選擇器,能針對特定元素進行設置。CSS有名叫層疊樣式表,基本上被選中的元素的子元素能繼承它的樣式,但其子元素如果設置了樣式,也能覆寫它,就像板頁巖這樣累在一起。隨著布局表格這樣落后的布局方式的式微,CSS越來越受到人們的重視。但IE6對CSS的支持不足與各種層不窮的bug,或者是某些大型網站對CSS的不合理使用,CSS的體積膨脹起來了。維護它們可是一件麻煩事,如何讓元素顯示出想要的樣式,我們就必須對權重這個概念有所了解。權重你可以說是針對樣式規則的,也可以說針對選擇符。之所以這樣說,因為有一個重要的標識符! important可以放到樣式聲明的最后,用來無視本文重點說的權重等級。我覺得最好還是不要用這東西,首先IE6對它支持不好,要支持它需要把一個樣式規則分開寫,另,用多了會嚴重擾亂CSS的權重等級。
有關CSS權重等級的介紹最早見于W3C這篇文章,聽說IE5是最早支持CSS的,不知哪個早一點呢?很明顯IE是沒有完全照足它來實現。在《Calculating a selector's specificity》一章,它粗略地用a、b、c、d來對樣式規則進行評估,給出每一個的得分(1 或 0),但沒有給出最終值的計算方式。
- a:如果這個元素應用了行內樣式,它才分配此值為1。怎么是行內樣式呢?就是標簽內使用style="...."的方式來設置樣式,我覺得這是很愚蠢的行為,徒然增加頁面的體積,也非常不好維護,和使用那些純表示樣式的元素差不多,如big、small、b、u、strike 等等。這樣做法,我個人覺得,瀏覽器其實是為它分配了一個特別的ID(實質上IE也是為頁面上每個元素分配了一個uniqueId),然后把它置于樣式表的最下方,于是就沒有其他樣式能覆蓋它了。
- b:指一個樣式規則的選擇符存在id選擇器。比如上面的body#jq-interior ,不過這樣有點累贅了。我看了許多CSS選擇器的實現,還有我在做選擇器的經驗,body完全沒有必要。一個選擇符就相當于一個選擇器群組,它由各種各樣的選擇器組成。選擇器得到一個符合CSS選擇符結構的字符串,如果它足夠聰明的話,會先對字符串進行trim操作,然后進行掃描,看有沒有id選擇器,有的話會砍掉前面的部分,然后再用正則對其進行肢解……換言之,id選擇器具有強烈的排它性,只有并聯選擇器可以容忍它。
- c:指一個樣式規則的選擇符是否存在類選擇器與偽類選擇器(:hover,:link,:active,:target)。這些基本上CSS2.1的東西,CSS3增加的基本是結構偽類還有一個selection偽元素,沒有破壞這個評分體系。
- d:這個權重最低了,指選擇符里存在標簽選擇器,與偽元素。何為偽元素呢?前面有::的東西就是偽元素了。注意,早期的偽元素也和偽類一樣,只有一個冒號。這可能是后來w3c心血來潮,把它們分離出來(css3規范),造成今天的樣子。
雖然到目前為止,我們已經知道a的權重肯定大于b,而b大于c,d最小,但這實在不好計算,對于接著下來的示例也不好解說。于是我引進外國另一個補充方案,它出于這篇名叫《CSS: Specificity Wars》的有才文章。。它把abcd當成算術上的個、十、百、千這樣的計數單位,各自相乘最后一加,優先級就一目了然啦。我們甚至可以將它們轉化為以下一個直觀的圖示。
好了,我們開始分析一下w3c的示例,看它能給我們什么多余的信息。
| /*by 司徒正美 All rights reserve*/ |
| *???????????? {}? /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ |
| /* 通配符選擇器權重為0,在IE中,它無法區分元素節點與注釋節點 */ |
| li??????????? {}? /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ |
| li:first-line {}? /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ |
| ul li???????? {}? /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ |
| /*這里存在后代選擇器的概念,但計算權重時像它這樣的關系選擇器會被進一步肢解,當成兩個標簽選擇器了。*/ |
| ul ol+li????? {}? /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ |
| /* 無視后代選擇器與相鄰選擇器,只看它里面的選擇器的成分 */ |
| h1 + *[rel=up]{}? /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ |
| /* 這個相鄰選擇器由標簽選擇器與屬性選擇器組成,屬性選擇器為10 */ |
| ul ol li.red? {}? /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ |
| /*無視后代選擇器,3個標簽與1個類選擇器,類(className)在DOM中的位置比較顯赫, |
| 擁有專門的getElementByClassName,等級為c,合計得分13 */ |
| li.red.level? {}? /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ |
| /*兩個類選擇器與一個標簽選擇器,合計得分21 */ |
| #x34y???????? {}? /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ |
| /*getElementById,在頁面上獲得元素最快的方式,權重為b,得分100 */ |
| style=""????????? /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */ |
| /*行內樣式,得分1000,會覆蓋內部樣式或外部樣式的設置*/ |
最后總結一下,十大選擇器與偽元素的權重情況:
?
選擇器 表達式或示例 說明 權重
| ID選擇器 | #aaa | ? | 100 |
| 類選擇器 | .aaa | ? | 10 |
| 標簽選擇器 | h1 | 元素的tagName | 1 |
| 屬性選擇器 | [title] | 詳見這里 | 10 |
| 相鄰選擇器 | selecter + selecter | 拆分為兩個選擇器再計算 | ? |
| 兄長選擇器 | selecter ~ selecter | 拆分為兩個選擇器再計算 | ? |
| 親子選擇器 | selecter > selecter | 拆分為兩個選擇器再計算 | ? |
| 后代選擇器 | selecter selecter | 拆分為兩個選擇器再計算 | ? |
| 通配符選擇器 | * | ? | 0 |
| 各種偽類選擇器 | 如:link, :visited, :hover, :active, :target, :root, :not等 | 10 |
| 各種偽元素 | 如::first-letter,::first-line,::after,::before,::selection | 1 |
總結
以上是生活随笔為你收集整理的CSS选择器的权重详解的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。