也來談談CSS層疊

網頁最終呈現的樣子是各類CSS聲明最終疊加到一塊兒的效果,咱們如下面的HTML文檔爲例:css

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Document</title>
  <style> h1 { font-size: 20px; } </style>
</head>
<body>
  <h1 style="font-size: 10px">h1 title</h1>
</body>
</html>
複製代碼

稍微有點HTML和CSS基礎的人都能看出,h1最終呈現的字體大小是10px,由於內聯樣式的優先級更高。html

h1的字體大小有3處聲明

打開Chrome開發工具,能夠看到對h1的字體大小有三處聲明。瀏覽器決定最終採用的哪一個值,是經過各類考量的。各處聲明的PK過程咱們稱之爲層疊。PK的勝負由如下三個方面決定:瀏覽器

  1. 該元素的樣式聲明來自哪裏(Origin: 來源)?
  2. 該聲明的特殊性怎麼樣(specificity: 特殊性)?
  3. 這些聲明誰先誰後(Order of Appearance: 出現前後)?

咱們下面對這三個方面逐一討論。工具

來源(Origin)

這裏的來源指的是CSS聲明在哪裏?CSS標準中將Origin分爲三大主類:開發工具

  1. Author Origin。網站的開發人員本身寫的樣式
  2. User Origin。瀏覽網頁的用戶本身加的定製樣式
  3. User agent Origin: 用戶代理給的默認樣式。好比開頭的例子中Chrome給h1默認2em的字體大小。

根據來源,瀏覽器評判出了聲明的重要性(Importance)。評判標準很簡單:字體

  1. 第一隊列: User Agent設置了!important的重要性最高,User設置的!important 其次,較低的是Author的!important 聲明。
  2. 第二隊列: Author的普通申明;User的普通申明;User agent的普通申明。

在層疊PK中,若是相同的選擇器重要性不一樣,那麼Origin這一層的PK就決出了勝負。網站

以下例子:spa

image

在Origin這一層的PK中:翻譯

1號是User的普通申明; 2號選手是用戶的!important聲明; 3號選手是User agent的普通聲明 因此 2號勝出 👏 👏 👏 👏代理

Specificity(特殊性)

若是兩個屬性的聲明重要性不分上下,這時候該PK特殊性了,特殊性是對選擇器而言的

w3標準裏面這樣描述特殊性的計算:

A selector’s specificity is calculated for a given element as follows:

  • count the number of ID selectors in the selector (= A)
  • count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= B)
  • count the number of type selectors and pseudo-elements in the selector (= C)
  • ignore the universal selector

翻譯並本身組織語言以下:

一個選擇器的特殊性這樣計算:

統計ID選擇器的數量(記爲A)

統計類選擇器、屬性選擇器、僞類選擇器的數量(記爲B)

統計元素選擇器和僞元素選擇器的數量(記爲C)

這裏推薦一個在線計算選擇器Specificity的網站:specificity.keegan.st/

在線計算selector的specificity

咱們用一個三元組來記錄一個選擇器的特殊性,例如:

ul    ---->  (0, 0, 1)
ul, ul   ---->  (0, 0, 2)
#list    ----> (1, 0, 0)
#list #sub-list li  ---> (2, 0, 1)
#list .list-item ---> (1, 1, 0)
複製代碼

那麼獲得三元組以後怎麼比較兩個三元組的優先級呢?

  • 比較A,大的勝出
  • A相同,比較B,B大的勝出
  • 最後比較C

一樣舉個🌰:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Document</title>
  <style> h1 { color: green; } h1#title { color: red; } h1.title { color: blue; } </style>
</head>
<body>
  <h1 id="title" class="title">h1 title</h1>
</body>
</html>
複製代碼

h1最終呈現的樣子是紅色:

image

在上面三條聲明中,選擇器對應的特殊性以下:

選擇器組 ID選擇器數量 類或屬性選擇器數量 元素或僞類選擇器數量 特殊性 結果
h1#title 1 0 1 (1, 0, 1) 👏👏👏
h1.title 0 1 1 (0, 1, 1) 💔
h1 0 0 1 (0, 0,) 💔

出現順序(Order of Appearance)

無需多言,前兩輪PK沒有結果的按照出場前後順序後來居上,決定最終勝負。

繼承

有CSS聲明的元素退場了,沒有CSS聲明的只能靠繼承或者默認樣式了。

某些樣式聲明會繼承到子元素(如顏色、字體大小),有些則不會(如border等)。

總結

CSS 層疊是考慮樣式來源、選擇器的特殊性、以及繼承來決定最終效果的過程。

相關文章
相關標籤/搜索