CSS选择器的优先级冲突(类型选择器 vs 类选择器)

6

我从这个教程中了解了选择器优先级。但是在某些情况下,我对其行为感到困惑。我有一个HTML元素:

<input class="top_bar_login_form_input" type="text"  name="email" placeholder="Prijavno ime">

问题在于另一个选择器的属性会覆盖类的属性。如上图所示,类被不太具体的选择器覆盖。元素被选择,这比类更不具体。我认为这种行为背后的唯一推理是,即使它与元素不匹配,.inputbox 类也会被计算在决定优先级时。为什么类型选择器会覆盖类选择器呢?

2
你要问问题吗? - keyboardSmasher
@keyboardSmasher:你也把他打败了 :D - Patt Mehta
我想了解为什么类型选择器会覆盖类,我将编辑我的帖子。 - Borut Flis
2个回答

11

TL;DR 答案

第一个规则比第二个规则更具体,因为它的选择器既有类型部分又有属性部分,因此具有优先权:

input[type="text"] { }         /* type + attribute for specificity */
.top_bar_login_form_input { }  /* only class for specificity, so *less* specificity */

较长的回答

你可能会认为,按照MDN关于优先级的页面的规定,属性选择器type="text"比类选择器更具体:

以下是按优先级递增的选择器列表:

  • 通用选择器
  • 类型选择器(例如,p
  • 类选择器(例如,.example
  • 属性选择器(例如,[type="radio"]
  • 伪类(例如,:hover
  • ID 选择器(例如,#example
  • 内联样式(例如,style="font-weight:bold;"

以上引用是在本回答撰写时的MDN文章中。

为什么这是误导性的:

(感谢@BoltClock的洞见。)

上述内容看起来是正确的,但这是因为在进行属性选择器时,通常会将元素包含在选择器中(例如,input[type="text"])。然而,其中隐藏了一些诡计:元素选择器input也是起作用的。

假设我们有以下标记:

<input class="my-class" type="text" value="some value" />

以下场景中,输入会呈现为红色
[type="text"] { color: green; }
.my-class { color: red; }             /* last rule matched */

如果我们反转场景规则,输入将呈现为绿色
.my-class { color: red; }
[type="text"] { color: green; }       /* last rule matched */

这是因为两个选择器的特异性相等。现在,在属性规则中引入input选择器将使它们中的一个更加特殊,这可以在此情景中看到:
input[type="text"] { color: green; }  /* most _specific_ rule matched */
.my-class { color: red; }

W3规范让我感到头疼,但是它详细说明了为什么上述代码可以生效。此外,参见@BoltClock的回答和这些代码示例中的评论获取有关计算特异度的信息。


1
抱歉,但这是MDN完全错误的地方...类、属性和伪类都是同样具体的。请查看我的答案,了解选择器行为背后的真正原因。 - BoltClock
1
@Borut Flis:IE6将一系列链接类.A.B.C视为最后一个类选择器.C,因此它的权重仅为1个类。其他浏览器将正确计算3个类。这是我所知道的唯一区别,但这与本文无关。 - BoltClock
@BoltClock 哈哈,你当时还点了赞,尽管在刚才的编辑之前,我似乎“责怪”了你的错误答案:D。我的错,现已更正! - Jeroen
input[class="my-class"]input[type="text"] 有什么区别? - Ari
@SoursopTree 很容易测试,不是吗?;-) - Jeroen
显示剩余6条评论

7
你的元素在第一条规则中与input[type="text"]匹配。虽然.inputbox选择器不匹配它,但这并不影响优先级,因为逗号分隔的选择器列表只计算列表中最具体的选择器来匹配一个元素。如果没有选择器与其匹配,则它根本不计入。
第一条规则覆盖第二条规则的原因是类选择器和属性选择器具有相等的特异性。伴随(或陪伴)属性选择器的input类型选择器使其比单独的类选择器更具优势:
/* 1 attribute, 1 type -> specificity = 0-1-1 */
input[type="text"]

/* 1 class             -> specificity = 0-1-0 */
.top_bar_login_form_input

因此,第一个选择器比第二个更具体,而不是相反。

如果您将类选择器与类型结合使用,例如input.top_bar_login_form_input,则选择器将保持平衡,并且第二个规则将覆盖第一个规则。


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