網頁最終呈現的樣子是各類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
打開Chrome開發工具,能夠看到對h1的字體大小有三處聲明。瀏覽器決定最終採用的哪一個值,是經過各類考量的。各處聲明的PK過程咱們稱之爲層疊。PK的勝負由如下三個方面決定:瀏覽器
咱們下面對這三個方面逐一討論。工具
這裏的來源指的是CSS聲明在哪裏?CSS標準中將Origin分爲三大主類:開發工具
根據來源,瀏覽器評判出了聲明的重要性(Importance)。評判標準很簡單:字體
在層疊PK中,若是相同的選擇器重要性不一樣,那麼Origin這一層的PK就決出了勝負。網站
以下例子:spa
在Origin這一層的PK中:翻譯
1號是User的普通申明; 2號選手是用戶的!important聲明; 3號選手是User agent的普通聲明 因此 2號勝出 👏 👏 👏 👏代理
若是兩個屬性的聲明重要性不分上下,這時候該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/
咱們用一個三元組來記錄一個選擇器的特殊性,例如:
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)
複製代碼
那麼獲得三元組以後怎麼比較兩個三元組的優先級呢?
一樣舉個🌰:
<!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最終呈現的樣子是紅色:
在上面三條聲明中,選擇器對應的特殊性以下:
選擇器組 | ID選擇器數量 | 類或屬性選擇器數量 | 元素或僞類選擇器數量 | 特殊性 | 結果 |
---|---|---|---|---|---|
h1#title | 1 | 0 | 1 | (1, 0, 1) | 👏👏👏 |
h1.title | 0 | 1 | 1 | (0, 1, 1) | 💔 |
h1 | 0 | 0 | 1 | (0, 0,) | 💔 |
無需多言,前兩輪PK沒有結果的按照出場前後順序後來居上,決定最終勝負。
有CSS聲明的元素退場了,沒有CSS聲明的只能靠繼承或者默認樣式了。
某些樣式聲明會繼承到子元素(如顏色、字體大小),有些則不會(如border等)。
CSS 層疊是考慮樣式來源、選擇器的特殊性、以及繼承來決定最終效果的過程。