樣式規(guī)則有三種來源,分別為:
外部樣式表或style元素中的CSS rules。如:
p{color:blue;}
這里的外部樣式表包括瀏覽的樣式、用戶聲明的樣式(正常聲明和重點(diǎn)聲明)、作者的樣式(正常和重點(diǎn))。
內(nèi)聯(lián)的style屬性,如:
<p style=”color:blue” ></p>
HTML元素的視覺屬性,如:
<td bgcolor=”blue”></td>
由于元素有自己的HTML屬性,后面兩者都能很容易的和元素匹配上。
對第一個(gè)的處理就有些麻煩,如果按一般的想法,為每個(gè)元素查找匹配的規(guī)則而遍歷整個(gè)樣式表,這將是一個(gè)非常艱巨的任務(wù)。瀏覽器又是怎么做的呢?瀏覽器會分析樣式表的時(shí)候會建立一些hash map,這些hash map有通過ID映射的,有通過CLASS映射的,有通過TagName映射的,還有一個(gè)通用的hash map用來映射其它的。在樣式分析完過后,CSS規(guī)則(css rules)都會被增加到這些hash map的某一個(gè)中。如果這個(gè)規(guī)則的選擇器是ID選擇器,就會添加到ID map里面;如果這個(gè)規(guī)則的選擇器是class選擇器,就會添加到class map里,等等,復(fù)合選擇器通常由最右邊的部分決定。這樣對元素進(jìn)行規(guī)則匹配就很快捷了。在Mozilla下(其它的可能也差不多),引擎先從分析完過后的樣式表中(即那些hash map)選出跟元素部分匹配的css規(guī)則,這些css規(guī)則并不一定都能應(yīng)用在這個(gè)元素上,還需要其它的操作來找出精確匹配的css規(guī)則。引擎這時(shí)就會分析這些部分匹配的css規(guī)則的選擇器,從右到左進(jìn)行分析,直到發(fā)現(xiàn)這個(gè)規(guī)則是精確匹配或是不匹配的從而放棄這條規(guī)則。假設(shè)定義了下面的樣式規(guī)則:
p.error {color:red}#messageDiv {height:50px}div {margin:5px}table div{margin:10px;}
第一個(gè)規(guī)則將會被添加到class map里面,第二個(gè)被添加到id map里,第三、四個(gè)添加到tag map里面。
<p class=”error”>an error occurred </p><div id=” messageDiv”>this is a message</div>
首先會嘗試為p 元素匹配,通過class關(guān)鍵字error在 class map里找到p.error這條規(guī)則。div 元素相關(guān)的規(guī)則在id map和tag map里,為#messageDiv,div,table div。接下就是要找出精確匹配的,#message,div很容易就能完成對div的匹配。對于table div,引擎從右到左分析規(guī)則的選擇器,找到了table,而這里的div元素沒有table的祖先元素,所以放棄這條規(guī)則,匹配完成。接下去就會去處理別的,如相對單位到絕對單位的轉(zhuǎn)換、構(gòu)建style context等等 。
此前見一些人說id選擇器的CSS規(guī)則速度是最快的,我想應(yīng)該是誤解吧。page speed的Optimize browser rendering里也沒有這種提法。沒有想出最佳實(shí)踐的方法,也不知道CSS的改善得到的優(yōu)化在什么樣的數(shù)量級上,還望有人能指點(diǎn)。謝謝了。
新聞熱點(diǎn)
疑難解答
圖片精選