前言
通常我們在設定連結的一些偽類(link
,visited
,hover
,active
)樣式時,要讓不同的狀態顯示正確的樣式,我們需要按一定的順序設定這些偽類的樣式。這裡我就按CSS2規範中推薦的順序進行介紹,即 link-visited-hover-active,可記為 LoVe-HAte
。
要想弄明白為什麼是這個順序,首先我們需要知道,CSS在確定應當向一個元素應用哪些樣式時,這通常不僅需要考慮 繼承,還要考慮宣告的 特殊性,另外需要考慮宣告本身的來源,這個過程就成為 層疊。下面我們分別來看看特殊性
、繼承
和 層疊
這3種機制之間的關聯。
特殊性
在實際的應用中,我們都知道一個元素可以通過多種選擇器來進行選擇,如ID選擇器、類選擇器等等,具體可看CSS選擇器詳解。由不同選擇器組成的選擇元素的方式暫且稱之為 規則 吧。考慮以下3對規則,當然每對規則都選擇同樣的元素:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/* 規則1 */ h1 { color: red; } body h1 { color: purple; } /* 規則2 */ h2.grape { color: purple; } h2 { color: silver; } /* 規則3 */ html > body table tr[id="totals"] td ul > li { color: maroon; } li#answer { color: navy; } |
顯然,每一對規則中只有一個勝出,因為所匹配的元素只能是某一種顏色。那麼怎麼知道哪一個規則更強呢?
答案就在於每個選擇器的特殊性。通過計算選擇器的特殊性值,特殊性最高的規則將會勝出並被利用。 這裡先預留一個問題,如果特殊性相等的兩個規則將如何確定應用?後面的層疊
再介紹。
特殊性值
特殊性值表述為4個部分,如:0,0,0,0。一個選擇器的具體特殊性如下確定:
- 對於選擇器中給定的各個ID屬性值,加0,1,0,0。
- 對於選擇器中給定的各個類屬性值、屬性選擇或者偽類,加0,0,1,0。
- 對於選擇器中給定的各個元素和偽元素,加0,0,0,1。
- 結合符和通配選擇器
*
對特殊性沒有任何貢獻,加0,0,0,0。 - 內聯樣式特殊性為1,0,0,0,因此內聯宣告的特殊性最高。
- 標誌為
!important
的宣告並沒有特殊的特殊性值,此時該宣告為重要宣告,超過所有非重要宣告。
通過以上的介紹,我們就可以計算出本節剛開始介紹的3組規則的特殊性值及被應用的規則:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/* 規則1 */ h1 { /* 0,0,0,1 */ color: red; } body h1 { /* 0,0,0,2 (元素應用該規則) */ color: purple; } /* 規則2 */ h2.grape { /* 0,0,1,1 (元素應用該規則) */ color: purple; } h2 { /* 0,0,0,1 */ color: silver; } /* 規則3 */ html > body table tr[id="totals"] td ul > li { /* 0,0,1,7 */ color: maroon; } li#answer { /* 0,1,0,1 (元素應用該規則) */ color: navy; } |
繼承
基於繼承機制,樣式不僅應用到指定的元素,還會應用到它的後代元素。下面的例子幫你瞭解繼承是如何工作的:
1 2 3 |
ul { color: red; } |
1 2 3 4 5 6 7 8 9 10 11 12 |
<div> <ul> <li>ul下的第一個li</li> <li>ul下的第二個li</li> <li>ul下的第三個li</li> </ul> <ol> <li>ol下的第一個li</li> <li>ol下的第二個li</li> <li>ol下的第三個li</li> </ol> </div> |
效果:
- ul下的第一個li
- ul下的第二個li
- ul下的第三個li
- ol下的第一個li
- ol下的第二個li
- ol下的第三個li
原理就是將宣告 color: red;
應用到 ul
元素時,這個元素會採用該宣告。然後將這個值再沿著文件樹向下傳播到後代元素,並一直繼承,直到再沒有更多的後代元素繼承這個值為止。值絕對不會向上傳播,也就是說,元素不會把值向上傳遞到其祖先。
重要:繼承值是完全沒有特殊性的,因此特殊性值為0,0,0,0的特殊性也比其高,說明繼承值很容易被其他方式中的宣告取代。
層疊
在 特殊性
一節中我們預留了一個問題:如果特殊性相等的兩個規則將如何確定應用?假設有以下規則:
1 2 3 4 5 6 |
h1 { color: red; } h1 { color: blue; } |
哪一個會佔上風?這兩個規則的特殊性都是0,0,0,1,所以它們的權重相等,都應當應用到元素,但這是不可能的,因為一個元素不可能既是紅色又是藍色(實際是藍色)。因此這裡 層疊
就出場了,先看看層疊規則:
下面分別介紹規則中後三條規則。
按權重和來源排序
根據第二條規則,如果兩個樣式規則應用到同一個元素,而且其中一個規則有 !important
標誌,這個重要規則將勝出.
1 2 3 |
p { color: gray !important; } |
1 |
<p style="color: black;">Well, <em>hello<em> there!</p> |
效果:
Well, hello there!
另外,還要考慮規則的來源。來源權重由大到小的順序依次為:
- 讀者的重要宣告(有
!important
) - 創作人員的重要宣告(有
!important
) - 創作人員的正常宣告
- 讀者的正常宣告
- 使用者代理宣告
按特殊性排序
根據第三條規則,如果向一個元素應用多個彼此衝突的宣告,而且它們的權重相同,則按特殊性排序,最特殊的宣告最優先。
1 2 3 4 5 6 |
p#bright { color: silver; } p { color: black; } |
1 |
<p id="bright">Well, hello there!</p> |
效果:
Well, hello there!
按順序排序
最後,根據第四條規則,如果兩個規則的權重、來源和特殊性完全相同,那麼在樣式表中後出現的一個會勝出。
1 2 3 4 5 6 |
h1 { color: red; } h1 { color: blue; } |
1 |
<h1>我是藍色的標題1</h1> |
效果:
我是藍色的標題1
連結樣式順序
好了,通過前面的介紹,我想大家應該基本瞭解CSS是如何確定應當向一個元素應用哪些值的。回到前言說到的連結樣式順序,為了正確的表現所設定的樣式,我們必須按一定的順序進行樣式設定。根據CSS2規範中的推薦順序,即 link-visited-hover-active,宣告樣式如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
:link { color: blue; } :visited { color: purple; } :hover { color: red; } :active { color: orange; } |
根據之前的介紹,以上這些選擇器的特殊性都是一樣的:0,0,1,0。因此他們有相同的權重、來源和特殊性,因此與元素匹配的最後一個選擇器才會勝出。
正在 “點選” 的 未訪問 連結可以與其中3個規則匹配 —— :link
、:hover
、:active
,所以按照上面的宣告順序,:active
將勝出,這可能就是我們所期望的。
假設我們忽略這種常用的順序,而是按字母順序排列連結樣式,宣告樣式如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
:active { color: orange; } :hover { color: red; } :link { color: blue; } :visited { color: purple; } |
按照這種順序,任何連結都不會顯示 :hover
或者 :active
,因為 :link
和 :visited
規則後出現。所有連結都必須要麼是已訪問(:visited
),要麼是未訪問(:link
),所以 :link
和 :visited
樣式總是會覆蓋 :hover
或者 :active
。
當然連結樣式也可以根據自己的實際需要設定某一種順序,比如 link-hover-visited-active 這樣的一個順序,起到的效果是 只有未訪問的連結會有懸停樣式,已訪問的連結沒有懸停樣式。
最後,由於可以把偽類連結起來,所以可以不必擔心這些問題。以下規則可以任何順序列出,而不必擔心有什麼負面影響:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
:link { color: blue; } :visited { color: purple; } :link:hover { color: red; } :visited:hover { color: gray; } :link:active { color: orange; } :visited:active { color: silver; } |
結語
通過對連結樣式順序為什麼是 link-visited-hover-active 的解答,我希望幫助大家能加深瞭解CSS在確定應當向一個元素應用哪些樣式時的一些基本原理。