为什么我不能覆盖已有的伪元素?

9

我有两个相邻的CSS规则:

.some td:first-child:before {
    content:url('path/to/image.png')" " ;
}
.some .other:before {
    content:url('path/to/image2.png')" " ;
}

这里是HTML代码片段:

<table class="some">
<tr>
    <td class="other">Text goes here</td>
    <td>Some more text.</td>
</tr>
</table>

它们都应该应用于同一个表格单元格。没有类的那个是作为备选项的。但出于某种原因,它总是选择第一个规则而不是第二个规则。我知道第二个规则是有效的,因为如果我在Firebug中禁用第一个规则,它将被使用。 我错过了什么?

.some td.other:before 不起作用吗? - John H
2
第一个比第二个具有更高的特异性 - Jared Farrish
@JohnH:问题在于,“其他”会有所不同,如果没有特定类别的显式规则,则应该使用后备规则。 - DanMan
@JaredFarrish:为什么?第二个有两个类选择器,而第一个只有一个。如果匹配,它不应该使用那个吗? - DanMan
3
第一个选择器看起来是31(三个二级选择器加上一个元素选择器),第二个选择器是30(三个二级选择器,没有元素选择器)。查看如何计算选择器的优先级 - Jared Farrish
@JaredFarrish:你说得对。在.other之前添加一个td就可以解决问题了。需要阅读关于伪元素特异性的内容...谢谢。 - DanMan
3个回答

15

好的,直截了当地说,在阅读了一些文章后,这就是特异性:

  • Id: 100
  • 类: 10
  • 伪元素类: 10
  • 伪元素: 1
  • 元素: 1

因此,第一个选择器具有22的特异性,而第二个则只有21。显然,first-child似乎是伪类而不是伪元素。

最后,在.other之前添加td就可以解决问题,因为文档顺序优先级更高。


没错,伪类就像一个类一样(在这种情况下,一个类名将被分配给所有第一个元素),而伪元素是DOM中的一个新元素,在这种情况下,它将被插入到所讨论的元素之前。这样说清楚了吗? - Mr Lister
可以争论很久,但是类并不是元素。就像你的例子中,some 不是一个元素,只有带有 class="some" 的表格才是。即使你将类名更改为听起来像元素的名称,例如 class="theThirdTable",它仍然不是一个元素! - Mr Lister

3
第一个规则比第二个规则更具体,因此在两个选择器都有效的情况下,更具体的选择器将覆盖其他选择器。
阅读this文章,了解如何克服具有冲突样式的复杂性。简要概述一下,以下是如何计算特异性。
+--------------------+--------------------+-----------------------------------+
|    Type            |   Specific Value   |  Example                          |
+--------------------+--------------------+-----------------------------------+
|  Inline Style      |   1000             | style="color: #f00;"              |
+--------------------+--------------------+-----------------------------------+
|  Id                |   100              | #text { color: #f00; }            |
+--------------------+--------------------+-----------------------------------+
|  Classes           |   10               | .text { color: #f00; }            |
+--------------------+--------------------+-----------------------------------+
|  Pseudo Classes    |   10               | a:hover { color: #f00; }          |
+--------------------+--------------------+-----------------------------------+
|  Pseudo Elements   |   10               | a:first-child { color: #f00; }    |
+--------------------+--------------------+-----------------------------------+
|  Elements (tag)    |   1                | a { color: #f00; }                |
+--------------------+--------------------+-----------------------------------+

基本上,类选择器比标签选择器更具体。让我们计算一下你的特异性。

  • 对于第一个规则:31
  • 对于第二个规则:30

因此,第一个规则胜出。

您可以增加第二个规则的特异性,例如:

.some tr td.other:before {
    content:url('path/to/image2.png') ;
}

这是计算出的结果为33,要覆盖第一个样式规则。


问题在于,它总是使用第一个,而不是第二个。 - DanMan
@DanMan,抱歉,我计算了特异性,你是正确的,已更新答案。 - Starx

2

我相信这与特定性有关。尝试在第二个规则中添加!important,看看是否起作用。


5
!important 是一种最后的手段,只有在其他方法都失败时才使用。 - Mr Lister
2
同意这个警告。但在这种情况下,快速查看是否可以覆盖是一个不错的建议,回答它是否与特定性有关,而无需确定具体原因。 - Patrick M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接