130

研究特异性我偶然发现了这个博客 - http://www.htmldog.com/guides/cssadvanced/specificity/

它指出特异性是 CSS 的评分系统。它告诉我们元素值 1 分,类值 10 分,ID 值 100 分。它还在上面说这些点是总计的,总量是选择器的特异性。

例如:

body = 1 分
body .wrapper = 11 分
body .wrapper #container = 111 分

因此,使用这些要点,我希望以下 CSS 和 HTML 会导致文本为蓝色:

#a {
    color: red;
}

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o {
  color: blue;
}
<div class="a">
  <div class="b">
    <div class="c">
      <div class="d">
        <div class="e">
          <div class="f">
            <div class="g">
              <div class="h">
                <div class="i">
                  <div class="j">
                    <div class="k">
                      <div class="l">
                        <div class="m">
                          <div class="n">
                            <div class="o" id="a">
                              This should be blue.
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

为什么当 15 个班级等于 150 分而 1 个 ID 等于 100 分时,文本是红色的?

显然,这些点不只是总计。它们是串联的。在此处阅读更多相关信息 - http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html

这是否意味着我们的选择器中的类 = 0,0,15,0OR 0,1,5,0

(我的直觉告诉我是前者,因为我们知道 ID 选择器的特殊性如下所示0,1,0,0:)

4

7 回答 7

142

Pekka 的回答实际上是正确的,并且可能是思考这个问题的最佳方式。

然而,正如许多人已经指出的那样,W3C CSS 建议指出“连接三个数字 abc(在具有大基数的数字系统中)给出了特异性。” 所以我的极客只需要弄清楚这个基地有多大。

事实证明,用于实现此标准算法的“非常大的基数”(至少由 4 个最常用的浏览器* )是 256 或 2 8

这意味着使用 0 id 和 256 个类名指定的样式覆盖仅使用 1 id 指定的样式。我用一些小提琴对此进行了测试:

所以实际上有一个“积分系统”,但它不是以 10 为底的。它是以 256 为底的。这是它的工作原理:

(2 8 ) 2或 65536,乘以选择器中的 id 数

  • (2 8 ) 1或 256,乘以选择器中的类名数
  • (2 8 ) 0或 1,乘以选择器中的标记名数

这对于传达概念的粗略练习来说不是很实用。
这可能是有关该主题的文章一直使用基数 10 的原因。

***** [Opera 使用 2 16(见 karlcow 的评论)。其他一些选择器引擎使用无穷大——实际上没有积分系统(参见 Simon Sapin 的评论)。]

2014 年 7 月更新:
正如 Blazemonger 在今年早些时候指出的那样,webkit 浏览器(Chrome、Safari)现在使用的基数似乎高于 256。也许 2 16,比如 Opera?IE 和 Firefox 仍然使用 256。

2021 年 3 月更新:
Firefox 不再使用 256 作为基础。

于 2012-08-13T12:44:01.563 回答
30

好问题。

我不能确定——我设法找到的所有文章都避免了多个类的例子,例如这里——但我假设在比较类选择器和 ID 之间的特异性时,类是用 a 计算的仅值15,无论它多么详细。

这符合我在特异性表现方面的经验。

但是,必须有一些类的堆叠,因为

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o

比更具体

.o

我唯一的解释是堆叠类的特异性仅针对彼此而不是针对 ID 计算。

更新:我现在中途明白了。它不是积分系统,关于重 15 分的班级的信息是不正确的。这是一个由 4 部分组成的编号系统,在这里得到了很好的解释。

起点是4位数:

style  id   class element
0,     0,   0,    0

根据W3C 关于 specificity 的解释,上述规则的具体值是:

#a            0,1,0,0    = 100
classes       0,0,15,0   = ... see the comments

这是一个具有非常大(未定义?)基数的编号系统。

我的理解是,因为基数很大,所以第 4 列中的任何数字都无法击败第 3 列中大于 0 的数字,第 2 列、第 1 列也是如此……这是正确的吗?

我很想知道是否有人比我更懂数学可以解释编号系统以及当单个元素大于 9 时如何将其转换为十进制。

于 2010-05-11T08:28:59.973 回答
9

当前的Selectors Level 4 工作草案很好地描述了 CSS 中的特异性:

特异性是通过依次比较三个分量来比较的:A值越大的特异性越特异性;如果两个A值并列,则B值越大的特异性越特异性;如果两个B值也并列,则c值越大的特异性越特异性;如果所有值都相同,则两个特性相等。

这意味着值 A、B 和 C 完全相互独立。

15 个类不会给你的选择器 150 的特异性得分,它给它的B值为 15。单个A值足以压倒它。

作为一个比喻,想象一个有 1 个祖父母、1 个父母和 1 个孩子的家庭。这可以表示为1,1,1。如果父母有 15 个孩子,那不会突然让他们成为另一个父母(1,2,0)。这意味着父母比他们只有一个孩子(1,1,15)承担的责任要多得多。;)

相同的文档还继续说:

由于存储限制,实现可能对ABc的大小有限制。如果是这样,则必须将高于限制的值限制在该限制范围内,而不是溢出。

这是为了解决浮士德的回答中提出的问题,2012 年的 CSS 实现允许特异性值相互溢出。

早在 2012 年,大多数浏览器都实现了 255 的限制,但这个限制被允许溢出。255 个班级的A,B,c特异性得分为0,255,0,但 256 个班级溢出且A,B,c得分为1,0,0。突然间,我们的B值变成了A值。Selectors Level 4 文档通过声明永远不允许溢出限制来完全解决这个问题。通过此实现,255和 256 类将具有相同的 A,B,c分数0,255,0

浮士德的答案中给出的问题已经在大多数现代浏览器中得到修复。

于 2016-03-14T16:56:14.913 回答
8

我目前正在使用这本书CSS Mastery: Advanced Web Standards Solutions

第 1 章第 16 页说:

为了计算规则的具体程度,每种类型的选择器都被分配了一个数值。然后通过将每个选择器的值相加来计算规则的特异性。不幸的是,特异性不是以基数 10 计算的,而是一个高的、未指定的基数。这是为了确保高度特定的选择器(例如 ID 选择器)永远不会被许多不太具体的选择器(例如类型选择器)覆盖。

(强调我的)和

选择器的特异性分为四个组成级别:a、b、c 和 d。

  • 如果样式是内联样式,则 a = 1
  • b = id 选择器的总数
  • c = 类、伪类和属性选择器的数量
  • d = 类型选择器和伪元素选择器的数量

它接着说,您通常可以以 10 为底进行计算,但前提是所有列的值都小于 10。


在您的示例中,id 不值 100 分;每个都值得[0, 1, 0, 0]点。因此,一个 id 优于 15 个类,因为[0, 1, 0, 0]它大于[0, 0, 15, 0]高基数系统。

于 2012-02-16T19:01:41.570 回答
5

我喜欢将特异性排名与奥运会奖牌表进行比较(金牌优先法——首先基于金牌数量,然后是银牌,然后是铜牌)。

它也适用于您的问题(一个特异性组中的大量选择器)。特异性分别考虑每个组。在现实世界中,我很少看到有十几个选择器的情况)。

这里也有相当不错的特异性计算器。您可以将示例(#a 和 .a .b .c .d .e .f .g .h .i .j .k .l .m .n .o)放在那里并查看结果。

里约 2016 年奥运会奖牌表的示例如下所示 在此处输入图像描述

于 2017-02-02T23:09:43.503 回答
3

我不相信博客的解释是正确的。规范在这里:

http://www.w3.org/TR/CSS2/cascade.html#specificity

类选择器中的“点”加起来不能比“id”选择器更重要。它只是不能那样工作。

于 2010-05-11T08:44:50.397 回答
1

我会这样说:

Element < Class < ID

我认为如果它是相同的倍数,它们只会叠加到你得到的东西。所以一个类总是会覆盖元素,ID 总是覆盖类,但是如果它是 4 个元素中的哪一个,其中 3 是蓝色,1 是红色,它将是蓝色的。

例如:

.a .b .c .d .e .f .g .h .i .j .k .l
{
color: red;
}

 .m .n .o
{
color blue;
}

应该变成红色。

请参阅示例 http://jsfiddle.net/RWFWq/

“如果 5things 说红色和 3 说蓝色好,我会变红”

于 2010-05-11T08:38:09.907 回答