CSS選擇器原理
瀏覽器是如何讀取選擇器泰讽,以識別樣式例衍,并將相應(yīng)的樣式附于對應(yīng)的HTML元素昔期,達到美化頁面的效果。Chris
Coyier曾在《Efficiently Rendering CSS》一文中說過“瀏覽器讀取你的選擇器佛玄,遵循的原則是從選擇器的右邊到左邊讀取硼一。換句話說,瀏覽器讀取選擇器的順序是由右到左進行”梦抢。比如說:
div.nav > ul li a
上面的實例來說般贼,瀏覽器首先會嘗試在你的HTML標簽中尋找“a”元素,接著在匹配“l(fā)i和ul”奥吩,最后在去匹配“div.nav”哼蛆。這就是前成所主的“選擇器從右到左的原則”。
選擇器的最后一部分霞赫,也就是選擇器的最右邊(在這個例子中就是a[title]部分)部分被稱為“關(guān)鍵選擇器”腮介,它將決定你的選擇器的效率如何?是高還是低端衰。
老版本的瀏覽器可以過濾掉不匹配的選擇器叠洗,而直接匹配更高效的選擇器。記得David Hyatt在《Writing efficient CSS for use in the Mozilla UI》說過:“這個關(guān)鍵選擇器可以大大提高選擇器的性能旅东,少檢查一個給定的元素規(guī)則灭抑,就可以更有效的將樣式匹配給對應(yīng)的HTML元素〉执”那么如何讓關(guān)鍵選
擇器更有效名挥,性能化更高呢?其實很簡單主守,主要把握一點“越具體的關(guān)鍵選擇器禀倔,其性能越高”
提高選擇器效率
那么什么樣類型的選擇器,其性能高参淫?什么樣的類型的選擇器性能低呢救湖?下面我們就針對兩個問題來展開具體的學(xué)習(xí)。
CSS選擇器的效率
如果你閱讀了本站的有關(guān)于選擇器類型的介紹的話涎才,你對選擇器并不會感到陌生鞋既。就算你沒讀過,我想CSS選擇器不會讓我們覺得是新東西耍铜,比如我們
常用的基本選擇器“元素標簽選擇器div”邑闺、“id選擇器#header”、“類選擇器.class”棕兼,或者說我們很少見的偽類選擇器“:focus”以
及更復(fù)雜的css3選擇器“:nth-child”等等陡舅。
選擇器有一個固有的效率,我們來看Steve Souders給排的一個順序:
id選擇器(#myid)
類選擇器(.myclassname)
標簽選擇器(div,h1,p)
相鄰選擇器(h1+p)
子選擇器(ul > li)
后代選擇器(li a)
通配符選擇器(*)
屬性選擇器(a[rel="external"])
偽類選擇器(a:hover,li:nth-child)
上面九種選擇器的效率是從高到低排下來的伴挚,基中ID選擇器的效率是最高靶衍,而偽類選擇器的效率則是最底灾炭。詳細的介紹大家還可以點擊Writing efficient CSS selectors。
綜合上面的順序颅眶,我們清楚的知道蜈出,id和類名用于關(guān)鍵選擇器上效率是最高的,而CSS3的仿偽類和屬性選擇器涛酗,雖然使用方便铡原,但其效率卻是最低的。我們下面一起來看幾個實例的對比:
div #myid
效率要比下面的高:
#myid div
第一種選擇器比第二種選擇器效率高商叹,大家或許會問為什么眷蜈?其實根據(jù)前面所介紹的我們就不難理解了,因為第一個選擇器的“關(guān)鍵選擇器”使用了
“ID選擇器”沈自,而第二個選擇器的“關(guān)鍵選擇器”使用的是“標簽選擇器”,對比下來辜妓,“ID選擇器”效率高過“標簽選擇器”枯途,所以說第一個選擇器的效率要
高于第二個選擇器。
在類名或ID名前面加上標簽也會致使選擇器效率變低的籍滴,比如說:
div
myid
上面兩個選擇的效率要高于下面的選擇器:
p#mydiv
p.myclassname
來自Mozilla的幾點建議
David在《Use efficient CSS selectors》中介紹了幾種書寫高效率的CSS選擇器的方法酪夷,下面我將他們移到這里來讓大家參考:
寫道
1 避免普遍規(guī)則
2 不要在ID選擇器前加標簽名或類名
3 不要在類名選擇器前加標簽名
4 盡可能使用具體的類別
5 避免使用后代選擇器
6 標簽分類規(guī)則中不應(yīng)該包含一個子選擇器
7 子選擇器的問題
8 借助相關(guān)繼承關(guān)系
9 使用范圍內(nèi)的樣式表
如果你不夠清楚上面所講的是什么,你可以點擊這里孽惰,他會讓你更容易了解這些規(guī)則晚岭。
我們應(yīng)該怎么做
前面說“ID選擇器”的效率是最高的,那么今天我們寫樣式坦报,為了提高選擇器的效率,是不是我們要在每一個文檔的HTML元素中都加入ID名呢狂鞋?
我想這樣的做法是沒有的片择。對于一個有語義的代碼編寫和如何提高性能,以前他們之間如何的平衡骚揍?其實這個選擇器的效率低一點字管,對于大多數(shù)網(wǎng)站來說并不會有太
大的影響,但對于一個大型的網(wǎng)站信不,產(chǎn)生大量的流量這就會有差別了嘲叔,也就很值得我們?nèi)λM行優(yōu)化。那么我們就很有必要的去了解他們是如何工作抽活,比如說硫戈,一
般情況下哪些選擇器的使用效率更高。來看兩個簡單的例子:
#myid
上面的選擇器高于下面的:
p#myid
后者的寫法我發(fā)現(xiàn)還是有很多朋友這樣寫下硕,但我不知道你為什么需要在ID前面加一個標簽掏愁?難道你同一個頁面會有多個相同的ID不成歇由?
我們接下來在來看一個實例,用于列表上的果港,比如說我們制作導(dǎo)航菜單的:
#nav a
高效于:
#nav li a
上面只是介紹了兩個常碰到的實例沦泌,在這里說這兩個實例,主要目的是讓你在今后的編寫樣式時辛掠,能注意這方面的的細節(jié)谢谦,從而加快你的代碼效率。