CSS 從入門到放棄系列:CSS的選擇器和優先級
CSS的選擇器和優先級
CSS的N種選擇器
!important
其實這個玩意不算什麽選擇器,放在這只是為了突出這個選擇器優先級或者說權重的從高到低而已。。
內聯方式(行間樣式)
<div style="width:100px;height: 100px; background-color: red"></div>
詳解見我的另一篇文章CSS的四種引用方式
ID選擇器(ID selectors)
通過設置元素的 id 屬性為該元素制定ID。ID名由開發者指定。每個ID在文檔中必須是唯一的。在寫樣式表時,ID選擇器是以#開頭的。
類選擇器(Class selectors)
通過設置元素的 class 屬性,可以為元素指定類名。類名由開發者自己指定。 文檔中的多個元素可以擁有同一個類名。在寫樣式表時,類選擇器是以英文句號(.)開頭的。
偽類/屬性(Pseudo-classes selectors)
CSS偽類是加在選擇器後面的用來指定元素狀態的關鍵字。比如,:hover 會在鼠標懸停在選中元素上時應用相應的樣式。(:checked:enabled:disabled。。。。)
元素選擇器(類型選擇器)
類型選擇器匹配文檔語言元素類型的名稱。類型選擇器匹配文檔樹中該元素類型的每一個實例
h1 {font-family: sans-serif;}
通用選擇器(通配符)
通配符使用星號*表示,意思是“所有的”。*會匹配所有的元素,因此針對所有元素的設置可以使用*來完成,用的最多的例子如下:*{margin:0px; padding:0px;}
CSS選擇器的優先級
關於選擇器優先級,很多人實際開發中遇到過坑,然後一般都是處在解決問題為上,而很少有機會扒拉一下到底裏面是個啥,現在就這個問題談談我的理解。
權重計算法
這是網上大多數人會采用的一種算法,搜搜博客園也是很多教程介紹的方法,首先來看看對於選擇器權重的定義。
!important Infinity(無窮大)
行間樣式 1000
id 100
class|屬性|偽類 10
通配符 1
有了以上定義,就很好解釋了當選擇器應用的時候通過權重相加得出最終結論,然而現實總是殘酷的,這種理論雖說解決了部分問題,但卻是錯誤的理解,可能下面的倆個例子
/* 按照這種計算方法,樣式一的權重值是11,樣式二的權重值是10,如果這兩條規則用於同一個元素,則該元素應該是紅色。實際結果卻是藍色。至於為什麽會這樣,見下面 */ /* 樣式一 */ body header div nav ul li div p a span em {color: red} /* 樣式二 */ .count {color: blue}
/* 張鑫旭大佬曾經在Firefox做了這樣一個demo
256個class選擇器可以幹掉1個id選擇器
並總結Firefox等瀏覽器所有的類名(classes)都是以8字節字符串存儲的,8字節所能hold的最大值就是255. 所以你想啊,當同時出現256個class, 勢必會越過其邊緣,溢出到id區域。
Opera瀏覽器class類名的存儲是以16字節的字符串。因此,該瀏覽器要想發生class溢出到id的話,需要連續65536個class。
*/
#id {
background: darkblue;
}
.c000.c001.c002.c003.c004.c005.c006.c007.c008.c009.c010.c011.c012.c013.c014.c015.c016.c017.c018.c019.c020.c021.c022.c023.c024.c025.c026.c027.c028.c029.c030.c031.c032.c033.c034.c035.c036.c037.c038.c039.c040.c041.c042.c043.c044.c045.c046.c047.c048.c049.c050.c051.c052.c053.c054.c055.c056.c057.c058.c059.c060.c061.c062.c063.c064.c065.c066.c067.c068.c069.c070.c071.c072.c073.c074.c075.c076.c077.c078.c079.c080.c081.c082.c083.c084.c085.c086.c087.c088.c089.c090.c091.c092.c093.c094.c095.c096.c097.c098.c099.c100.c101.c102.c103.c104.c105.c106.c107.c108.c109.c110.c111.c112.c113.c114.c115.c116.c117.c118.c119.c120.c121.c122.c123.c124.c125.c126.c127.c128.c129.c130.c131.c132.c133.c134.c135.c136.c137.c138.c139.c140.c141.c142.c143.c144.c145.c146.c147.c148.c149.c150.c151.c152.c153.c154.c155.c156.c157.c158.c159.c160.c161.c162.c163.c164.c165.c166.c167.c168.c169.c170.c171.c172.c173.c174.c175.c176.c177.c178.c179.c180.c181.c182.c183.c184.c185.c186.c187.c188.c189.c190.c191.c192.c193.c194.c195.c196.c197.c198.c199.c200.c201.c202.c203.c204.c205.c206.c207.c208.c209.c210.c211.c212.c213.c214.c215.c216.c217.c218.c219.c220.c221.c222.c223.c224.c225.c226.c227.c228.c229.c230.c231.c232.c233.c234.c235.c236.c237.c238.c239.c240.c241.c242.c243.c244.c245.c246.c247.c248.c249.c250.c251.c252.c253.c254.c255 {
background: darkred;
}
test {
display: block;
height: 100px;
width: 100px
}?
<test id="id" class="c000 c001 c002 c003 c004 c005 c006 c007 c008 c009 c010 c011 c012 c013 c014 c015 c016 c017 c018 c019 c020 c021 c022 c023 c024 c025 c026 c027 c028 c029 c030 c031 c032 c033 c034 c035 c036 c037 c038 c039 c040 c041 c042 c043 c044 c045 c046 c047 c048 c049 c050 c051 c052 c053 c054 c055 c056 c057 c058 c059 c060 c061 c062 c063 c064 c065 c066 c067 c068 c069 c070 c071 c072 c073 c074 c075 c076 c077 c078 c079 c080 c081 c082 c083 c084 c085 c086 c087 c088 c089 c090 c091 c092 c093 c094 c095 c096 c097 c098 c099 c100 c101 c102 c103 c104 c105 c106 c107 c108 c109 c110 c111 c112 c113 c114 c115 c116 c117 c118 c119 c120 c121 c122 c123 c124 c125 c126 c127 c128 c129 c130 c131 c132 c133 c134 c135 c136 c137 c138 c139 c140 c141 c142 c143 c144 c145 c146 c147 c148 c149 c150 c151 c152 c153 c154 c155 c156 c157 c158 c159 c160 c161 c162 c163 c164 c165 c166 c167 c168 c169 c170 c171 c172 c173 c174 c175 c176 c177 c178 c179 c180 c181 c182 c183 c184 c185 c186 c187 c188 c189 c190 c191 c192 c193 c194 c195 c196 c197 c198 c199 c200 c201 c202 c203 c204 c205 c206 c207 c208 c209 c210 c211 c212 c213 c214 c215 c216 c217 c218 c219 c220 c221 c222 c223 c224 c225 c226 c227 c228 c229 c230 c231 c232 c233 c234 c235 c236 c237 c238 c239 c240 c241 c242 c243 c244 c245 c246 c247 c248 c249 c250 c251 c252 c253 c254 c255"></test>?
所以上面的所謂的權重的定義是不符合實際的,但是不能否認它是對選擇器權重值的一種總結,拿來理解下也不是不可,那有沒有正確的解法呢,下面的四組計算法倒是可以作為一個答案
1.如果規則是寫在標簽的style屬性中(內聯樣式),則A=1,否則,A=0. 對於內聯樣式,由於沒有選擇器,所以B、C、D的值都為0,即A=1, B=0, C=0, D=0(簡寫為1,0,0,0,下同)。
2.計算該選擇器中ID的數量。如果有則B=1,沒有B=0(例如,#header 這樣的選擇器,計算為0, 1, 0, 0)。
3.計算該選擇器中偽類及其它屬性的數量(包括class、屬性選擇器等,不包括偽元素)。(例如, .logo[id=‘site-logo‘] 這樣的選擇器,計算為0, 0, 2, 0)
4.計算該選擇器中偽元素及標簽的數量。(例如,p:first-letter 這樣的選擇器,計算為0, 0, 0, 2)。
按照四組計算的正確方法,上面第一個例子中的樣式一權重值應該是0, 0, 0, 11,樣式二的權重值是0, 0, 1, 0。
根據規範,計算權重值時,A,B,C,D四組值,從左到右,分組比較,如果A相同,比較B,如果B相同,比較C,如果C相同,比較D,如果D相同,後定義的優先特殊的!important
上面最初定義了一個!important的無窮大的概念,其實總結起來就是css2中的規定:!important 用於單獨指定某條樣式中的單個屬性。對於被指定的屬性,有 !important 指定的權重值大於所有未用 !important 指定的規則。如果多條規則中都對同一個屬性指定了 !important。這時候 !important 的作用相互抵銷,依然按照ABCD四組計算比較。
綜上所述:!important 的作用只有在具有唯一性時才能提現,但是我們永遠無法預料自己什麽時候又需要覆蓋一個已經指定了 !important 的屬性,所以最好的辦法就是:不要使用 !important。
關於inherit(繼承)
<style>
.list .item { color: red }
</style>
<ul class="list">
<li class="item">
<span>某些文字</span>
</li>
</ul>
上例中,樣式規則並未針對 span 標簽指定 color 屬性, 但是 span 中的文字會顯示為紅色, 這就是因為 span 的 color 屬性默認值為 inherit.對於 inherit 的屬性,只要記住一點:繼承而來的屬性值,權重永遠低於明確指定到元素的定義。只有當一個元素的某個屬性沒有被直接指定時,才會繼承父級元素的值。 例如:
<style>
span { color: blue }
.list .item { color: red }
</style>
<ul class="list">
<li class="item">
<span>某些文字</span>
</li>
</ul>
同樣的例子, 第一條規則的權重是 0,0,0,1, 第二條規則的權重是 0,0,2,0. 雖然第二條規則的權重更高,但是它是針對 li 元素的直接指定,並不是針對 span 元素定義的,所以計算 span 的 color 屬性權重值時,實際上就是 inherit 的紅色與直接指定的藍色的對比。按照規則,只要有直接指定的值(藍色),就不會再取繼承的值(紅色),所以 span 中的文字顯示為藍色。
以上就是對於css選擇器和優先級的總結,
參考:
關於CSS權重(優先級)的理解
深入理解CSS權重
CSS 從入門到放棄系列:CSS的選擇器和優先級