首頁 > web前端 > css教學 > 主體

CSS元素選擇器的運作方式介紹

青灯夜游
發布: 2020-11-11 17:56:57
轉載
1814 人瀏覽過

CSS元素選擇器的運作方式介紹

推薦教學:CSS影片教學

在前端工程師的日常工作中,使用CSS 元素選擇器是稀鬆平常的事;無論你是寫一般的CSS 還是需要經過編譯的SASS,SCSS,LESS等,最後都被編譯成一行一行的CSS 樣式屬性,最後交給瀏覽器解析並套用。但是你想過沒有這是如何實現的呢?

瀏覽器渲染

我們先來看看瀏覽器的渲染步驟:

CSS元素選擇器的運作方式介紹

CSS 在被瀏覽器載入後,會被解析成CSSOM 樹,並嘗試與Dom 疊加成渲染樹,接著進行運算位置、渲染等步驟。這樣看來,CSS 屬性套用的關鍵就在於如何從 CSS 轉換成 CSSOM 樹,以及怎麼把 CSSOM 套用到 DOM 上去。

CSSOM樹

當我們寫下一組CSS 樣式時,例如:

#id .class h4 + p {
   ...
}
登入後複製

瀏覽器在解析它時,你可能會認為CSS 會依照從左到右右的依序找出#id>.class>h4>p,最後套用,但實際上瀏覽器解析CSS 的順序是由右到左p>h4>.class>#id

很違背直覺對吧?但如果考慮到效能問題,從右到左的解析會比從左到右強很多。

假設這有這樣的HTML:

<p>
    </p><p>
        </p><p>
            ...
        </p>
        <p>
            </p><p>
                ...
            </p>
            <p>
                ...
            </p>
        
    
    <p>
        </p><p>
            </p><p>
                ...
            </p>
        
    
登入後複製

以及這邊五條CSS 樣式規則:

#p1 .c .d {}
.f .c .d {}
.a .c .e {}
#p1 .f {}
.c .d {}
登入後複製

讓我們模擬一下,如果把CSS 從左到右解析,將會產生類似這樣的CSSOM 樹:

CSS元素選擇器的運作方式介紹

透過<p class="「" d></p>透過<p class="「" d></p> 中的.d 來思考,這樣的CSSOM 樹在套用樣式時,必須對所有的樣式規則進行檢查,以確認樣式規則是否會影響到

.d
    ,到最後才能確定可能會影響到
  • .d 的樣式規則有這三條:
  • #p1 .c .d
  • ##.f .c .d
.c .d

以此類推,每個DOM 樹上的元素,都必須便利所有的樣式規則,才可以取得個別的樣式,這樣會造成大量冗餘的計算,進而嚴重影響效能。

CSS元素選擇器的運作方式介紹反過來,如果將前面的CSS 由右到左進行解析,CSSOM 樹則可能會如下:

和前面的例子一樣,從

.d 的角度來看,由於會被樣式規則影響到的目標元素,已經全都集中在第一層了,所以就不用再去便利整個CSSOM 樹了,甚至只需要檢查.d

以下的子屬性變數是否符合實際DOM 結構,再將所有符合的樣式規則重新取回,便能完成

. d

對元素的樣式規則套用。

從右到左的解析順序能夠將所有共享的規則路徑收攏在一起,當瀏覽器進行屬性比對時,就不用再便利整個CSSOM 樹,大大的減少了無效的比對計算。

也可以換個方式思考:在 HTML 的結構中,一個元素可以有無數個子元素,但只能有一個父元素,由子找父(由下往上)搜尋絕對是比較快的。

套用樣式

將 CSSOM 樹解析出來之後就能夠和 DOM 結合了嗎?如果真的有這麼簡單就太好了。
  • 除了開發者定義好的CSS 檔案外,還有幾個地方可能會定義樣式規則,影響畫面的渲染:
  • HTML 的inline style 設定
  • 瀏覽器預設值(就是CSS reset/normalize 要覆寫的東西)

瀏覽器的使用者偏好設定

瀏覽器負責處理CSS 的部分,會吧前面所有的東西以及CSS 檔案定義的樣式規則分別整理成單獨的樣式規則群組(CSS 規則集),內容記載了樣式規則、目標屬性等資訊。

目標屬性
  • 為了提升後面的計算效率,瀏覽器的CSS 處理內核會依照樣式規則組中個別規則的目標屬性將其分組存放;一共分為以下四組
  • idRules
  • classRules
  • tagNameRules

universalRules

這樣在取用時,可以依據目標元素是否存在這個屬性,快速篩選出可能會套用的樣式。

套用規則######最後是套用規則。瀏覽器會遵循以下順序和樣式規則權重套用所有的樣式規則:###
  • 瀏覽器的預設值
  • 瀏覽器的使用者偏好設定
  • 開發者定義的CSS
  • inline style
  • 加上!important 的樣式屬性

你可能會好奇:為什麼inline style 和開發者定義的CSS 會被另外處理?

我們可以回顧瀏覽器渲染的步驟,由於inline style 存在於DOM 元素中,只能在CSS 套用到DOM 上時才會接觸到,事前無法將兩者結合。

CSS 效率

實際上瀏覽器在這裡已經完成了最佳化機制;瀏覽器會自動將狀態一致的元素做成樣式快照。狀態一致就是要滿足以下幾個條件:

  • 沒有設定ID
  • tag 及class 必須完全一致
  • 沒有設定style 屬性
  • 樣式規則中不能使用各種同級選擇器(例如: :first-child 等)

  • ##由於上面的條件,以及前面討論到的CSS 運算過程,編寫CSS 時也有幾個地方可以稍微留心一下:
  • 由於樣式規則的目標屬性會分組存放,id 選擇器效率非常高,所以是不能與其他條件混用的。
不要寫過深的CSS 樣式規則

能不用inline style 就不要用,除了難以維護外,由於是存在於DOM 樹上,無法預先與其他樣式合併計算,所以效率也會大打折扣

如果能注意到這類典型的小細節,CSS 效率自然也可以大幅提升。

延伸認識了 CSS 選擇器之後,一定會很好奇,JavaScript 的元素選擇器又是怎麼一回事呢?這個問題可以參考 jQuery 的源碼,它是由左到右的解析,至為什麼為什麼不一樣,其實在文中也有答案,就留給你思考挖掘吧。

###更多程式相關知識,請造訪:###程式設計入門###! ! ###

以上是CSS元素選擇器的運作方式介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!