當你隨機打開一個頁面,查看源代碼,你會發現,同一個元素,不止有一個CSS選擇器及對應的樣式。而一個元素只能應用一個樣式,那麼一堆樣式中到底是應用哪個呢?這就涉及到CSS的層疊規則了。下面就來總結下CSS的層疊規則。css
概念:CSS中的層疊就是讓多個來源的樣式疊加在一塊兒,而後結合樣式的特殊性(後面詳細介紹)、繼承性,肯定最終應用的樣式。html
樣式的來源分五種:瀏覽器
一、瀏覽器默認的樣式;ruby
二、用戶自定義樣式。一些頁面中會提供一些讓用戶自定義字體大小顏色等的快捷鍵;ide
三、外部樣式,即<link>引用的CSS後綴文件;學習
四、內部樣式,即寫在<style></style>標籤內的樣式;字體
五、內聯樣式,即直接寫在style屬性內的樣式(如今的網頁設計強調結構、表現、行爲三者分離,因此這個仍是少用爲好。我會強迫性移除內聯樣式的,哈哈);spa
CSS權威指南中對樣式來源的分類分紅三種:設計
一、創做人員(上面提到的第3、4、5點均可歸到這一點)代理
二、讀者(用戶自定義樣式)
三、用戶代理(這個就是上面所說的瀏覽器默認樣式了)
來看一個例子:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <link rel="stylesheet" href="style.css" type="text/css"> 5 <style> 6 #p1 #p2{ 7 color:yellow; 8 } 9 .div1 .div2 #p1{ 10 color:green; 11 } 12 .div1 .div2 p{ 13 color:gray; 14 } 15 .div1 .div2 .impo{ 16 color:green; 17 } 18 .impo{ 19 color: brown !important; 20 } 21 </style> 22 </head> 23 <body> 24 <div class="div1"> 25 <div class="div2"> 26 <p id="p1">Hello world</p> 27 <p id="p2" style="color: red">Hello, how are you!</p> 28 <p class="impo">I'm important!</p> 29 </div> 30 </div> 31 </body> 32 </html> 33 34 Style.css文件的代碼: 35 .div1 .div2 #p1{ 36 color: blue; 37 }
這個例子中,這三行文字的顏色分別是什麼呢?相信大家不少人也知道了。答案先不揭曉,繼續往下看。
CSS2.1層疊規則是:
一、找出全部相關的規則,這些規則都包含與一個給定元素匹配的選擇器。
二、按顯式權重對應用到該元素的全部聲明進行排序,有!important標誌的聲明的權重要高於不帶!important標誌的聲明。
三、按來源對應用到給定元素的全部聲明進行排序。正常狀況下,創做人員的樣式要賽過讀者的樣式。有!important標誌的的讀者樣式要強於全部其餘樣式,包括有!important標誌的創做人員樣式。創做人員的樣式和讀者樣式鬥都比用戶代理的默認樣式強。
四、按特殊性對應用到給定元素的全部聲明進行排序,有較高特殊性的元素權重要大於有較低特殊性的元素。
五、按出現順序對應用到給定元素的全部聲明進行排序,後面出現的聲明權重要大於前面出現的聲明,即後定義的樣式會覆蓋前面定義的樣式。
簡單總結:找出一個給定元素的全部聲明後,先按顯式權重和來源進行排序。若是相同,則比較特殊性。若再相同,則比較順序。
根據以上的知識,咱們很明確知道了上面的例子三行文字的顏色是什麼了:
第一行是文字的顏色是green;第二行文字的顏色是red;第三行文字顏色是brown。
下面着重講解下選擇器的特殊性:
一、對於內聯樣式,特殊性首位加1,即1,0,0,0。
二、對於選擇器中出現的ID屬性值,加0,1,0,0, 有多少個ID值就在第二位加幾位。
三、對於選擇器中出現的類屬性值,屬性選擇及僞類,加0,0,1,0,共出現多少個就在第三位加幾位。
四、對於選擇器中出現的元素,以及僞元素,加0,0,0,1,共出現多少個就在第四位加幾位。
五、通配符對特殊性沒有任何貢獻,即特殊性是0,0,0,0。
六、結合符沒有特殊性,連0特殊性也沒有。
七、繼承的CSS徹底沒有特殊性,連0特殊性也沒有(CSS中的繼承是有選擇性的,並非所有CSS都繼承,像邊框屬性就不會繼承)。
注:僞元素選擇器包含如下幾種:
一、:first-line; 用於向文本的首行設置特殊樣式;
二、:first-letter; 用於向文本的首字母設置特殊樣式;
三、:before; 能夠在元素的內容前面插入新內容;
四、:after; 能夠在元素的內容以後插入新內容;
五、::selection 選擇被用戶選取的元素部分(CSS3中新加的選擇器);
下面再來看一個例子:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <style type="text/css"> 5 #content #main-content h2{ 6 color:red; 7 } 8 9 #content #main-content>h2{ 10 color:blue ; 11 } 12 body #content div[id="main-content"] h2{ 13 color:green; 14 } 15 16 #main-content div.paragraph h2{ 17 color:orange; 18 } 19 #main-content [class="paragraph"] h2{ 20 color:yellow; 21 } 22 div#main-content div.paragraph h2.first{ 23 color:pink; 24 25 } 26 </style> 27 28 </head> 29 <body> 30 <div id="content"> 31 <div id="main-content"> 32 <h2>學習HTML</h2> 33 <div class="paragraph"> 34 <h2 class="first">學習CSS</h2> 35 </div> 36 </div> 37 </div> 38 39 </body> 40 </html>
這兩個標題的顏色分別是什麼呢?
用剛剛講的特殊性規則計算下這六個樣式的特殊性:
第一個規則特殊性的值是:0,2,0,1
第二個規則特殊性的值是:0,2,0,1
第三個規則特殊性的值是:0,1,1,3
第四個規則特殊性的值是:0,1,1,2
第五個規則特殊性的值是:0,1,1,1
第六個規則特殊性的值是:0,1,2,3
這樣很明確知道了,特殊性最高的是第一和第二條規則,但第二條規則在後面,因此第一個標題的顏色是blue,第二個標題的顏色是red.
在這裏要重點提一下,0特殊性(通配符)和沒有特殊性(結合符和繼承)是有很大差異的,這種差異決不能忽視。
看下面的例子,就能夠看出二者的區別了:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <style type="text/css"> 5 *{ 6 color:gray; 7 } 8 h1#page-title{ 9 color:red; 10 } 11 </style> 12 </head> 13 <body> 14 <div> 15 <h1 id="page-title">Hello<em>world</em></h1> 16 </div> 17 </body> 18 </html>
這其中Meerkat的顏色是red,但Central的顏色是gray。由於通配符*的特殊性是0, 而繼承的CSS是沒有特殊性的,連0也沒有,因此,通配符的權重要大於繼承。
說了特殊性,這裏也順便引入一遍文章,這是對特殊性的另外一方面的說明。