了解 CSS 具體性的含義以及其重要性
當一個元素被多個具有不同選擇器的規則所影響時,會發生什麼情況?這些規則都影響相同的屬性。
例如,讓我們來談一談這個元素:
<p class="dog-name">Roger</p>
我們可以有以下規則:
.dog-name {
color: yellow;
}
還有另一個以 p
為選擇器的規則,它將顏色設置為另一個值:
p {
color: red;
}
還有一個以 p.dog-name
為選擇器的規則。哪個規則將優先於其他規則,為什麼?
這時要介紹一下具體性。最具體的規則將優先選擇。如果兩個或多個規則具有相同的具體性,則最後出現的規則將優先選擇。
對於初學者來說,實際上什麼是更具體的有點困惑。我想對於不常看這些規則的專家來說也是困惑的,或者只是忽視了它們。
如何計算具體性
具體性是使用一種約定方式來計算的。
我們有 4 個插槽,每個插槽的初始值為 0: 0 0 0 0
。最左邊的插槽最重要,最右邊的插槽最不重要。
就像十進制數字一樣:1 0 0 0
比 0 1 0 0
要大。
插槽 1
插槽 1 是最不重要的。
當我們有一個 類型選擇器 時,我們會增加這個值。類型就是標籤名稱。如果在規則中有多個類型選擇器,則按照該插槽中存儲的值進行遞增。
例子:
p {
} /* 0 0 0 1 */
span {
} /* 0 0 0 1 */
p span {
} /* 0 0 0 2 */
p > span {
} /* 0 0 0 2 */
div p > span {
} /* 0 0 0 3 */
插槽 2
第二個插槽的值增加 3 個方面:
- 類選擇器
- 偽類選擇器
- 屬性選擇器
每次規則遇到其中一個時,我們都會增加右邊第二列的值。
例子:
.name {
} /* 0 0 1 0 */
.users .name {
} /* 0 0 2 0 */
[href$='.pdf'] {
} /* 0 0 1 0 */
:hover {
} /* 0 0 1 0 */
當然,第 2 插槽的選擇器可以與第 1 插槽的選擇器結合使用:
div .name {
} /* 0 0 1 1 */
a[href$='.pdf'] {
} /* 0 0 1 1 */
.pictures img:hover {
} /* 0 0 2 1 */
類有一個不錯的技巧,你可以重複使用同一個類,增加具體性。例如:
.name {
} /* 0 0 1 0 */
.name.name {
} /* 0 0 2 0 */
.name.name.name {
} /* 0 0 3 0 */
插槽 3
插槽 3 中存儲的是在 CSS 文件中對你的具體性具有重大影響的 id
。
每個元素都可以有一個分配的 id
屬性,我們可以在樣式表中使用它來針對元素。
例子:
#name {
} /* 0 1 0 0 */
.user #name {
} /* 0 1 1 0 */
#name span {
} /* 0 1 0 1 */
插槽 4
插槽 4 受行內樣式的影響。任何行內樣式都優先於外部 CSS 文件中定義的任何規則,或者在頁面標頭中的 style
標籤內部定義的規則。
例子:
<p style="color: red">Test</p> /* 1 0 0 0 */
即使 CSS 中的任何其他規則定義了顏色,這個行內樣式規則也會被應用。除非使用了 !important
,這將填充插槽 5。
重要性
具體性在規則以 !important
結尾時不重要:
p {
font-size: 20px !important;
}
該規則將優先於具體性更高的任何規則。
在 CSS 規則中添加 !important
會使該規則比任何其他規則更重要,根據具體性規則,只有另一個規則也使用了 !important
,並且在其他不重要的插槽中具有更高的具體性時,其才能優先選擇。
技巧
一般來說,您應該使用所需的具體性,但不要過度使用。這樣,您可以創建其他選擇器來覆蓋前面規則設置的規則,而不會讓自己變得瘋狂。
!important
是 CSS 提供給我們的一個備受爭議的工具。許多 CSS 專家反對使用它。當嘗試應用一些樣式並且 CSS 規則具有很高的具體性,使得我需要使用 !important
來讓瀏覽器應用我的新 CSS 時,我會使用它。
但通常情況下,!important
應該不會出現在您的 CSS 文件中。
用於計算具體性的工具
您可以使用此網站 https://specificity.keegan.st/ 自動執行具體性計算。
這在您試圖弄清楚問題時非常有用,因為它可以作為一種良好的反饋工具。