CSS的低權重原則—避免濫用子選擇器
來自: https://segmentfault.com/a/1190000004926286
CSS設置的樣式是可以層疊的,如下面[代碼1][代碼1]
<style type="text/css"> span{font-size: 40px;} .test{color:red;} </style> <span class="test">CSS的低權重原則</span>
“CSS的低權重原則”既可以的到“font-size:40px”的樣式,又可以得到“color: red”的樣式。如果兩個不同選擇符設置的樣式有沖突,又會如何?如下面[代碼2][代碼:CSS層疊有沖突的情況]
<style type="text/css"> span{font-size: 40px;color:green} .test{color:red;} </style> <span class="test">CSS的低權重原則</span>
“CSS的低權重原則”顏色會是什么呢?是對“span”設置的“color:green”呢,還是第“.test”設置的“color:red”呢?這就涉及CSS選擇符的權重問題了。
CSS的選擇符是有權重的, 當不同選擇符的樣式設置有沖突時,會采用權重高的選擇符設置的樣式。 權重的規則是這樣的: HTML標簽的權重是1,class的權重是10,id的權重是100 ,例如p的權重是1,“div em”的權重是1+1=2,“strong.demo”的權重是10+1=11,“#test.red”的權重是100+10=110.
[代碼2]中,選擇符span的權重是1,“.test”的權重是10,所以“CSS的低權重原則”的color應該是red。
但是如果是如下[代碼3]時,又會如何呢?
<style type="text/css"> span{font-size: 40px;} .test{color:red;} .test2{color: green} </style> <span class="test test2">CSS的低權重原則</span>
span的標簽同時掛了test和test2兩個class,他們的權重都是10,那么“CSS的低權重原則”的color又該是哪個呢? 如果 CSS選擇符權重相同,那么樣式就遵循就近原則,哪個選擇符后定義,就采用哪個選擇符的樣式。 [代碼3]中test2后定義,所以color會采用“.test2”的設置為green。
如果改變“.test”和“.test2”定義的位置,如[代碼4]
<style type="text/css"> span{font-size: 40px;} .test2{color: green} .test{color:red;} </style> <span class="test test2">CSS的低權重原則</span>
那么 “CSS的低權重原則”的color就為red了。
需要強調的是就近原則指的是選擇符 的先后順序,而不是掛class名的先后順序, <span class="test test2">CSS的低權重原則</span> 和 <span class="test2 test">CSS的低權重原則</span> 沒有區別。
CSS選擇符權重是個容易被忽略的問題。但事實上如果不太注意選擇符的權重,常會出現意向不到的小麻煩。例如下面[代碼5]
<style type="text/css"> #test{font-size: 14px;} </style> <p id="test">CSS的選擇符權重很重要</p>
現在需要將“很重要”三個字設置為紅色,我們應該怎么做呢?方案一,利用子選擇器,如[代碼6]
<style type="text/css"> #test{font-size: 14px;} #test span{color: red} </style> <p id="test">CSS的選擇符權重<span>很重要</span></p>
方案二,新建class,如[代碼7]
<style type="text/css"> #test{font-size: 14px;} .font{color: red} </style> <p id="test">CSS的選擇符權重<span class="font">很重要</span></p>
很多工程師推薦使用方案一,因為使用子選擇器可以避免新增class,讓HTML代碼更簡潔,這么考慮是有道理的,但如果這時需求有變化,需要添加新的額文字進來,如[代碼8]
<style type="text/css"> #test{font-size: 14px;} #test span{color: red} </style> <p id="test">CSS的選擇符權重<span>很重要</span>,我們要小心處理</p>
要求我們將“小心處理”設置為綠色,我們可以這么做,如[代碼9]
<style type="text/css"> #test{font-size: 14px;} #test span{color: red} .font{color:green} </style> <p id="test">CSS的選擇符權重<span>很重要</span>,我們要<span class="font">小心處理</span></p>
本以為小心處理會被選擇符font設置為綠色,但它卻被選擇符權重更高的“#test span”設置成了紅色,子選擇器在無意中影響到了我們新添加的代碼。如果想要達到我們的預期,我們需要按代碼[9]重寫
<style type="text/css"> #test{font-size: 14px;} #test span{color: red} /* 選擇符權重為100+1=101 */ #test .font{color:green} /* 選擇符權重為100+10=110 */ </style> <p id="test">CSS的選擇符權重<span>很重要</span>,我們要<span class="font">小心處理</span></p>
而如果使用方案二呢?
<style type="text/css"> #test{font-size: 14px;} .test{color: red} /* 選擇符權重為100+1=101 */ .font2{color:green} /* 選擇符權重為100+10=110 */ </style> <p id="test">CSS的選擇符權重<span class="font">很重要</span>,我們要<span class="font2">小心處理</span></p>
因為沒有使用子選擇器,所以我們添加新代碼掛上新的class就可以順利的完成樣式的設置了。
使用子選擇器,會增加CSS選擇符的權重,CSS的選擇符權重越高,樣式越不易被覆蓋,所以除非確定HTML結構非常穩定,一定不會再修改了,否則盡量使用子選擇器。為了保證樣式容易被覆蓋,提高可維護性,CSS選擇符權重盡可能低。
少用子選擇器,就需要多添加class,在Web標準盛行的初期,很多工程師認為多添加class是不好的,如果能使用子選擇器就應該盡量使用,使用大量的class的做法叫做“多class癥”。在進過大量實踐后,我并不認為多class有太大的壞處,相反,與使用子選擇器相比,新添加class反而跟利于維護。