近期考慮對CSS進行一些重構,看著以前自己的代碼整個人凌亂了。于是做了一些調研寓娩,看到一些不一樣的地方給大家分享一下。
一呼渣、CSS的匹配規(guī)則
1棘伴、根據CSS定義位置來區(qū)別
平常所認為的優(yōu)先級規(guī)則,從根本上來講是片面的屁置。
默認樣式<外部樣式表<內部樣式表<行內樣式 //是片面的
瀏覽器默認樣式最低焊夸,行內樣式最高,這是肯定的缰犁。
但是外部樣式表和內部樣式表其實優(yōu)先級并沒有太大的區(qū)別淳地,只是我們一般都會在head中先引用外部樣式表,再定義內部樣式表帅容,才形成了以上的觀點颇象。(你完全可以把外部樣式表放到body的下面,雖然不太好但是規(guī)則是允許的)
對于所有的非行內自定義樣式(可以統(tǒng)一稱為樣式表)并徘,
樣式表的優(yōu)先級完全取決于被引入或者定義的位置遣钳。
2、根據選擇器的優(yōu)先級來確定
選擇器的優(yōu)先級規(guī)則為:ID > 偽類 > 屬性 > 類 > 元素 > 通配符麦乞,對于組合選擇器的優(yōu)先級就對以上規(guī)則從左到右依次進行比較蕴茴,知道可以得出結果劝评。
例如:#test_id div 則比#test_id .test_class的優(yōu)先級要低。
通常為了保證樣式的準確性倦淀,我們會使用較高優(yōu)先級的選擇器蒋畜,或者使用多種選擇器的組合形式。
3撞叽、!important
最高優(yōu)先級
二姻成、CSS選擇器解析規(guī)則
前面講到,為了保證樣式應用的準確性愿棋,會使用多種選擇器的組合形式科展。于是,就有了一些比較極端的寫法——總是或者盡量使用更多層級的選擇器組合糠雨。
從準確性來看才睹,毫無問題;從性能上看甘邀,這樣會有什么問題嗎琅攘?
顯然,這涉及到CSS的匹配規(guī)則鹃答。
1乎澄、從右到左的匹配規(guī)則
通常思維是選擇器指定越詳細,則越容易匹配测摔,性能越好置济。這種觀點建立的基礎是,對每一個CSS樣式去查詢匹配dom中的節(jié)點锋八,那么選擇器的詳細程度越高浙于,就越能減少查詢的冗余,性能越好挟纱。例如:
.test_class .test_span1{} // 樣式1
.test_class .test_div1 .test_span1{} // 樣式2
// 布局
<div class="test_class">
<div class="test_div1"><span class="test_span1">測試1</span></div>
<div class="test_div2"><span class="test_span2">測試2</span></div>
</div>
按照上述規(guī)則羞酗,樣式1會比樣式2多做一次比較,即對test_span2的比較紊服。
這種CSS查詢匹配dom節(jié)點的方式檀轨,就是常說的從左到右的匹配規(guī)則(針對CSS選擇器而言)——針對樣式1,從左到右匹配5次欺嗤,從右到左匹配7次参萄。
2、從右到左的匹配規(guī)則
還有一種思維是選擇器指定越精簡煎饼,則越容易匹配讹挎,性能越好。這種觀點建立的基礎是,對每一個dom節(jié)點去查詢匹配CSS中的樣式筒溃,那么選擇器的詳細程度越高马篮,查詢匹配的次數就越多,性能越差怜奖。例如:
.test_div1 .test_span{} // 樣式1
.test_class .test_div1 .test_span{} // 樣式2
// 布局
<div class="test_class">
<div class="test_div1"><span class="test_span">測試1</span></div>
</div>
按照上述規(guī)則浑测,針對“測試1”的樣式匹配,樣式1要比樣式2少1次匹配歪玲。這種dom節(jié)點查詢匹配CSS選擇器的方式尽爆,就是常說的從右到左的匹配規(guī)則(針對CSS選擇器而言)——針對樣式1,從左到右匹配3次读慎,從右到左匹配2次。
3槐雾、CSS選擇器匹配規(guī)則
事實上雖然上述兩種匹配方式都有一定到理論性夭委,但是結論只有一個——從右到左。至于原因募强,先來看一下一些有趣的回答株灸。
3.1 哲學思維
人可以選擇兩條路,但是真正走的卻只有一條擎值。
最根本的道理慌烧。
3.2 價值取向
英文順序一般先小后大,先具體后寬泛鸠儿,例如姓名是先名后姓屹蚊,地址是X號X街X城市X州、日期是日/月/年进每。
西方比較強調個體價值汹粤,中國比較強調家族觀念。
而從右到左正好符合了西方的個體價值觀田晚。
——很性感的思維嘱兼。
3.3、Sunday算法
這里只做了一個概述贤徒,具體的可以自己百科一下芹壕,還挺有意思的。
Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配接奈。其核心思想是:在匹配過程中踢涌,模式串發(fā)現不匹配時,算法能跳過盡可能多的字符以進行下一步的匹配鲫趁,從而提高了匹配效率斯嚎。
而從右向左也正符合這一算法。
3.4、瀏覽器加載方式
訪問網頁的整個過程在瀏覽器的表現:
請求數據--詞法語法解析--下載link文件--生成dom樹--構建render樹--繪制
而CSS樣式的匹配正是在構建render樹時進行的堡僻,所以需要采用對每個dom節(jié)點查詢匹配CSS選擇器的方式糠惫,即從右到左的匹配規(guī)則(從1、2可以知道這樣匹配的次數較少)钉疫。
三硼讽、結論
很顯然,我們在定義樣式的選擇器時牲阁,在準確表達的情況下固阁,應該盡量較少選擇器組合中的冗余,從一定程度上提升CSS的性能城菊。