【问题标题】:CSS precedence logicCSS 优先逻辑
【发布时间】:2012-08-16 05:14:21
【问题描述】:

在本例中:

http://jsfiddle.net/Ja29K/

<style>
  /* Default links */
  a {
    color: #0F0; /* Green */
  }

  /* Header links */
  #header a {
    color: #F00; /* Red */
  }

  /* Login link */
  #login {
    color: #00F; /* Blue */
  }
</style>

<header id="header">
  <p><a href="#">header link</a> is red</p>
  <p><a id="login" href="#">login link</a> is not blue</p>
</header>

登录链接必须是蓝色的不符合逻辑吗?

我知道声明有相同的来源和相同的重要性,因此需要对它们进行评分(选择器的特异性)。

为了计算选择器的特异性,我为每个选择器创建了一个表格:

A = 内联样式数:0
B = ID 数:0
C = 类数:0 b>
D = 元素数:0

所以login元素有3次与他的颜色相关的碰撞:a#header a#login

元素 (A, B, C, D)

a (0, 0, 0, 1) = 1
#header a (0, 1, 0, 1) = 101
#login (0, 1, 0, 0) = 100

选择器“#header a”获胜,因为它的得分最高。

但是

如果我们将选择器“#login”更改为“a#login”,我们将得到:
a#login (0, 1, 0, 1) = 101
选择器“#header a”丢失,因为平局赢得了最后宣布的。

所以,我无法理解的是:

由于“#header a”选择器引用了许多元素,而 ID 选择器(例如 #login)只引用了一个元素,因此我们希望将 ID 选择器声明应用于该元素是合乎逻辑的,对吗?我真的无法理解这个 CSS 优先逻辑,因为我认为 ID 选择器基本上必须是最具体的东西,就像内联样式一样。

P.S.:对不起我的英语不好:)

【问题讨论】:

  • 可能相关或不相关,但如果你有相同的特异性,最后一个总是赢。
  • @Jawad OP 知道...请阅读...
  • @Christoph:是的,我明白了。也许这就是我只评论的原因。
  • (0, 0, 0, 1) 不等于 1,(0, 1, 0, 1) 不等于 101。这不是特异性系统的工作原理。

标签: html css css-selectors css-specificity css-cascade


【解决方案1】:

这取决于具体 - 更具体,它会为你工作:

header a#login {
 color: #00F; /* Blue */
}​

【讨论】:

  • 或使用!important :-) 虽然这有助于解决问题,但它并不能真正回答问题。 id (#) 基本上是可能的最具体的东西。
  • @Imp !important 是一个非常糟糕的选择,不应在样式表中使用。
  • !important 不需要在样式表之外使用。但在某些情况下,它很有用。例如:如果您希望 .required 在页面中的任何位置显示为红色,即使更具体的样式将其涂成黑色。
  • @Blazemonger 很好,然后您需要一个具有.require 类的元素才能使用绿色字体。您增加了选择器的特异性,但由于最初的!important 而没有任何反应,因此您添加了另一个!important,这导致另一个重要的导致...最后,您的每个规则都有一个!important,而您回到了你应该首先编写干净的 CSS 的地方。
  • @Christoph 我无法想象你刚才描述的场景。
【解决方案2】:

不,根据选择器的逻辑,不是。

#header a#login 更具体。如果您将#header a 选择器减少为#header,则标题选择器和登录选择器将具有相同的特异性,并且将使用最后表达的规则(按照您的顺序从登录时的颜色)。如果您通过添加标签名称来增加登录选择器的具体性,情况也是如此。

【讨论】:

  • 这里的另一个最佳实践是使用#header #login 作为最后一条规则,使其推翻#header a 之一。
  • 问题是假设单个 id 选择器比 id 选择器更具体的标签。无论开发人员选择如何组织他们的 DOM,选择器都必须能够运行。浏览器唯一知道的是#login#header 都引用了具有注明id 属性的单个特定DOM 元素。 #header a 指的是基于 id 的规则的子集,因此比任何适用的(单个)基于 id 的规则更具体。
  • @AndréAbreu 您能否指出我的论点无法解释的地方?
  • @AndréAbreu 因为根据定义, (1, 0, 1) 大于 (1, 0, 0)。
  • @André #login a 更具体为 #login 尽管后者只能指代一个元素。术语“特定”意味着更严格的元素子集,因此#login 应该更具体。
【解决方案3】:

OP,也许您可​​以认为 CSS 先处理第一个参数(#header 和 #login),然后才处理第二个参数(“#header a”中的 a)。

所以在第一个进程中,它先变成红色,然后变成蓝色,但在第二个进程中,由于第二个参数中的“a”,它被覆盖为红色。

【讨论】:

【解决方案4】:

您看不到“特异性”,即哪个选择器针对的元素最少,而只是最重要的。

当然,通过区分#header aa#login 之类的东西,规则可以变得更加复杂。然而,这只会给整个系统增加更多的混乱。
这(c/w)也很可能会被如下滥用:header#header a - 这增加了更高的特异性,但也可以针对更多元素。

在我看来,这不会为系统增加更多价值,只会让它变得更复杂。

在编写 CSS 时,应始终尽量使规则尽可能短,以免出现性能问题。如果您需要覆盖规则,您仍然可以添加另一个 idclass - 除了正常的级联之外,这确实绰绰有余。

【讨论】:

  • @chirstoph 从哪个选择器针对最少元素的意义上看,看不到“特异性”,但如果存在一个只针对一个元素的选择器,只需应用它!就像内联样式一样 :)
  • 当我说“一个只针对一个元素的选择器”时,我说的是 ID 选择器。
  • @André 标签或类选择器也可能只针对一个元素,具体取决于标记。由于总是对选择器的所有部分进行评估,因此键选择器在选择器的具体程度方面没有“额外权重”。我同意,有时这很烦人,但这就是规范所定义的。
  • 规范甚至没有定义术语“键选择器”。但是,它确实定义了术语“选择器的主题”,它相似但不完全相同。
【解决方案5】:

解决这个问题只需将 #login 更改为 a#login 让 DOM 知道此命令特定于链接。

#header a#login 更具体,因为它指向 DOM 中的特定元素,而不仅仅是随机 id。

【讨论】:

    【解决方案6】:

    您似乎对特异性的概念很熟悉,即thouroughly described as part of w3 css specs。从算法的角度来看,规则声明中的选择器特异性值是平面加权或非位置。这意味着#header aa#login 具有相同的特异性,这意味着如果一个元素同时符合这两个规则,则后一个将优先。

    就个人而言,我花了更长的时间来接受具有语义特异性但没有计算价值的选择器。例如,ul liul&gt;li 具有相同的权重,尽管后者“感觉”更具体!

    我发现任何具有函数式编程背景的人都发现将特异性比较为四字节值更容易(这实际上接近于它在主要浏览器中的实现方式 - consequently overflowing the value when 256+ selectors of the same weight are used :)

    【讨论】:

    • 你可能会觉得this question很有趣;它着眼于为什么 ul liul&gt;li 被设计为同样具体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2018-12-15
    相关资源
    最近更新 更多