了解 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 00 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/ 自動執行具體性計算。

這在您試圖弄清楚問題時非常有用,因為它可以作為一種良好的反饋工具。