所謂CSS優(yōu)先級(jí),即是指CSS樣式在瀏覽器中被解析的先后順序;瀏覽器是通過優(yōu)先級(jí)來判斷哪些屬性值與元素最相關(guān)以決定并應(yīng)用到該元素上的。優(yōu)先級(jí)就是分配給指定的CSS聲明的一個(gè)權(quán)重,它由匹配的選擇器中的每一種選擇器類型的數(shù)值決定。
本教程操作環(huán)境:windows7系統(tǒng)、CSS3版、Dell G3電腦。
一、優(yōu)先級(jí)
所謂CSS優(yōu)先級(jí),即是指CSS樣式在瀏覽器中被解析的先后順序。
瀏覽器根據(jù)優(yōu)先級(jí)來決定給元素應(yīng)用哪個(gè)樣式,而優(yōu)先級(jí)僅由選擇器的匹配規(guī)則來決定。
內(nèi)聯(lián)》ID選擇器》偽類=屬性選擇器=類選擇器》元素選擇器【p】》通用選擇器(*)》繼承的樣式
二、優(yōu)先級(jí)計(jì)算:
上面說了,優(yōu)先級(jí)僅有選擇器決定,怎么個(gè)計(jì)算方法呢?
a、用a表示選擇器中ID選擇器出現(xiàn)的次數(shù)
b、用b表示類選擇器,屬性選擇器和偽類選擇器出現(xiàn)的總次數(shù)。
c、用c表示標(biāo)簽選擇器、偽元素選擇器出現(xiàn)的總次數(shù)
d、忽略通用選擇器
e、然后計(jì)算a*100+b*10+c的大小,這就是優(yōu)先級(jí)了。
權(quán)重:內(nèi)聯(lián)樣式1000》id選擇器100》class選擇器10》標(biāo)簽選擇器1
Note:
ID選擇器「如:#header」,Class選擇器「如:.foo」,屬性選擇器「如:[class]」,偽類「如::link」,標(biāo)簽選擇器「如:h1」,偽元素「如::after」,選擇器「*」
接下來從以下幾點(diǎn)深入分析優(yōu)先級(jí)。
1、優(yōu)先級(jí)計(jì)算無視DOM樹中的距離
開頭說明的例子:
<!DOCTYPE html> <html> <style type="text/css"> body h1 { color: green; } html h1 { color: purple; } </style> </head> <body> <h1>Here is a title!</h1> </html>
body h1和html h1的優(yōu)先級(jí)相同。
【推薦教程:CSS視頻教程 】
2、偽類選擇器,屬性選擇器和class選擇器的優(yōu)先級(jí)一樣
偽類=屬性選擇器=類選擇器
所以后面的會(huì)覆蓋前面的。
<!DOCTYPE html> <html> <meta charset="utf-8"> <style type="text/css"> :focus { color: red; } [class] { color: blue; } .classtest { color: green; } </style> </head> <body> <div class="classtest"> 什么顏色文字 </div> </body> </html>
如下圖類選擇器在后,所以覆蓋前面的樣式,所以文字綠色。
如下圖屬性選擇器在后,會(huì)覆蓋前面的類選擇器樣式,所以文本藍(lán)色。
focus同理,只有放后面才生效,否則會(huì)被偽類和屬性選擇器覆蓋
3、基于類型的優(yōu)先級(jí)
優(yōu)先級(jí)是根據(jù)選擇器的類型進(jìn)行計(jì)算的。
舉例:屬性選擇器盡管選擇了一個(gè)ID但是在優(yōu)先級(jí)計(jì)算中還是根據(jù)類型計(jì)算,因此即使選擇的是相同的元素,但I(xiàn)D選擇器有更高的優(yōu)先級(jí),所以* #foo設(shè)置的樣式生效。
<!DOCTYPE html> <html> <style type="text/css"> * #foo { color: green; } *[id="foo"] { color: purple; } </style> </head> <body> <p id="foo">I am a sample text.</p> </body> </html>
4、:not偽類不參與優(yōu)先級(jí)計(jì)
【:not】否定偽類在優(yōu)先級(jí)計(jì)算中不會(huì)被看做是偽類,但是,會(huì)把:not里面的選擇器當(dāng)普通選擇器計(jì)數(shù)。這句話有點(diǎn)不好理解,其實(shí)就是忽略掉:not,其他偽類(如:hover)參與CSS優(yōu)先級(jí)的計(jì)算,但是「:not」不參與計(jì)算。
舉個(gè)例子:
<!DOCTYPE html> <html> <style type="text/css"> div.outer p { color:red; } div:not(.outer) p { color: blue; } </style> </head> <body> <div class="outer"> <p>This is in the outer div.</p> <div class="inner"> <p>This text is in the inner div.</p> </div> </div> </body> </html>
該例子中,選擇器p.outer p 和選擇器p:not(.outer) p的優(yōu)先級(jí)是相同的,:not被忽略掉了,:not(.outer)中的.outer正常計(jì)數(shù)。
如果調(diào)換位置,inner元素會(huì)變成紅色
div:not(.outer) p { color: blue; } div.outer p { color:red; }
5、優(yōu)先級(jí)計(jì)算不升位
不要把權(quán)重簡(jiǎn)單的作為10進(jìn)制數(shù)字比較其大小。
a=1的規(guī)則優(yōu)先級(jí)將永遠(yuǎn)高于其他a=0的。
比如一個(gè)選擇器的a>0,b=0即使另外一個(gè)選擇器的a=0,b=12,c=12那么前者的權(quán)重依然更大??!
為證明我做了一個(gè)不現(xiàn)實(shí)的demo
<!DOCTYPE html> <html> <meta charset="utf-8"> <style type="text/css"> #test{ /*a=1*/ color: blue } div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest div.classtest{ /*b=12*/ color:green; } </style> </head> <body> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div class="classtest"> <div id="test" class="classtest"> 什么顏色文章 </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </body> </html>
可見文本顏色還是藍(lán)色??!
同樣有一個(gè)帶有10個(gè)id選擇器的規(guī)則,優(yōu)先級(jí)也不如內(nèi)聯(lián)樣式。
總之優(yōu)先級(jí)的計(jì)算不是基于十進(jìn)制升位的,后面的數(shù)優(yōu)先級(jí)再高也不能升到前一位。
6、其他
下面再給出一個(gè)經(jīng)典的例子,自己計(jì)算一下就明白了。
Examples: * /* a=0 b=0 c=0 -> specificity = 0 */ LI /* a=0 b=0 c=1 -> specificity = 1 */ UL LI /* a=0 b=0 c=2 -> specificity = 2 */ UL OL+LI /* a=0 b=0 c=3 -> specificity = 3 */ H1 + *[REL=up] /* a=0 b=1 c=1 -> specificity = 11 */ UL OL LI.red /* a=0 b=1 c=3 -> specificity = 13 */ LI.red.level /* a=0 b=2 c=1 -> specificity = 21 */ #x34y /* a=1 b=0 c=0 -> specificity = 100 */ #s12:not(FOO) /* a=1 b=0 c=1 -> specificity = 101 */
如果確實(shí)有棘手的情況,可以在Firebug中查看優(yōu)先級(jí)。Firebug中按照優(yōu)先級(jí)排序顯示規(guī)則,將優(yōu)先級(jí)更高的規(guī)則顯示在最上面,并將被覆蓋的規(guī)則用刪除線劃掉。
三、!import
為什么沒有把!import放在優(yōu)先級(jí)順序中,因?yàn)楣俜秸J(rèn)為!import和優(yōu)先級(jí)沒一點(diǎn)關(guān)系。
不建議使用!import
-
Never 絕不要在全站使用!import。
-
Only 只在需要覆蓋全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定頁(yè)面中使用
!important
-
Never 永遠(yuǎn)不要在你的插件中使用
!important
-
Always 要優(yōu)先考慮使用樣式規(guī)則的優(yōu)先級(jí)來解決問題而不是
!important
選擇元素時(shí)盡量不要多選,不要放寬選擇器的范圍。因?yàn)榉秶叫?,越具有針?duì)性,優(yōu)先級(jí)越高。
1、什么場(chǎng)合使用!import?
使用!import的場(chǎng)合也是有的,但是是在沒有別的解決方案的時(shí)候。
比如需要覆蓋內(nèi)聯(lián)樣式,因?yàn)閮?nèi)聯(lián)樣式的優(yōu)先級(jí)最高,只能用!import去覆蓋內(nèi)聯(lián)樣式。
還有一種情況
<style type="text/css"> #someElement p { color: blue; } p.awesome { color: red; } </style> </head> <body> <div id="someElement"> <p class="awesome">some text</p> </div> </body>
在外層有 #someElement
的情況下,你怎樣能使 awesome
的段落變成紅色呢?這種情況下,如果不使用 !important
,第一條規(guī)則永遠(yuǎn)比第二條的優(yōu)先級(jí)更高。這也是沒有別的辦法,如果用內(nèi)聯(lián)結(jié)果只會(huì)更糟糕。
2、怎樣覆蓋已有!import規(guī)則
a、再加一條!import的css語(yǔ)句,將其應(yīng)用到更高優(yōu)先級(jí)的選擇器(在原有基礎(chǔ)上添加額外的標(biāo)簽、類或者ID選擇器)。
幾個(gè)更高優(yōu)先級(jí)選擇器的例子:
table td {height: 50px !important;}.myTable td {height: 50px !important;}#myTable td {height: 50px !important;}
b、選擇器一樣,但添加的位置在原有聲明后面。因?yàn)橄嗤瑑?yōu)先級(jí),后邊定義的聲明覆蓋前面的。
相同選擇器的例子:
td {height: 30px !important;}td {height: 50px !important;}