如何计算 CSS 特异性的点

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

它指出,特异性是一个点评分系统的 CSS。它告诉我们元素值1分,类值10分,ID 值100分。它也继续说,这些点是总和,总量是选择器的特异性。

例如:

身体 = 1分
包装纸 = 11点
容器 # 容器 = 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分,文本是红色的?

显然,这些点不仅仅是总数,它们是连接在一起的

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

(我的直觉告诉我是前者,因为我们知道身份选择器的特异性看起来像这样: 0,1,0,0)

28015 次浏览

问得好。

我不能肯定地说——我找到的所有文章都避免使用多个类的例子,例如 给你——但是我认为,当涉及到比较 在类选择器和 ID 之间的特性时,无论它有多么详细,这个类只能用 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 对特异性的解释,上述规则的特异性值为:

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

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

我的理解是,由于基数非常大,所以第4列中的任何数字都无法超过第3列中的 > 0,第2列、第1列也是如此... ..。是这样吗?

我感兴趣的是,是否有比我更精通数学的人能够解释数字系统,以及当单个元素大于9时如何将其转换为十进制。

我会说:

Element < Class < ID

我认为它们只会堆积成取决于你得到的是相同数量的倍数。 所以 Class 将总是覆盖类的元素和 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/

“如果5个东西说红色,3个东西说蓝色,我就变成红色”

我不相信博客的解释是正确的,具体说明如下:

Http://www.w3.org/tr/css2/cascade.html#specificity

类选择器中的“点”加起来不会比“ id”选择器更重要。事情不是这样的。

我目前正在使用的书 CSS 掌握: 高级 Web 标准解决方案

第一章,第16页写道:

要计算规则的特定程度,需要分配每种选择器类型 一个数值。一个规则的特异性是通过 将它的每个选择器的值相加, 特异性不是以10为基数计算,而是以一个高的、未指定的基数计算 这是为了确保高度特定的选择器,如 ID 选择器,不会被很多不太特定的选择器覆盖, 例如类型选择器

(强调我的)和

选择器的特异性被分解为四个组成部分 水平: a,b,c,d。

  • 如果样式是内联样式,则 a = 1
  • B = id 选择符的总数
  • C = 类、伪类和属性选择器的数目
  • D = 类型选择符和伪元素选择符的数目

它接着说,您通常可以以10为基数进行计算,但只有在所有列的值都小于10的情况下才可以这样做。


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

Pekka 的答案是 差不多吧是正确的,而且可能是思考这个问题的最佳方式。

然而,正如许多人已经指出的那样,W3C CSS 建议指出: “将三个数字 a-b-c (在一个基数很大的数字系统中)连接起来可以提供特异性。”所以我内心的极客只能算出这个基地有多大。

结果表明,实现这个标准算法所使用的“非常大的基数”(至少4个最常用的浏览器使用的基数)是256或28

这意味着用0 id 和256个类名 威尔指定的样式将覆盖用1 id 指定的样式。我用一些小提琴测试了一下:

因此,实际上存在一个“点系统”,但它不是以10为基数,而是以256为基数。它是这样运作的:

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

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

对于粗略的练习来说,传达这个概念是不太实际的。
这可能就是为什么关于这个主题的文章一直使用10进制的原因。

Opera 使用216(参见 Karlow 的评论)。其他一些选择器引擎使用 无穷大ーー实际上是无分系统(参见 Simon Sapin 的评论)

2014年7月更新:
Blazemonger 在今年早些时候指出,webkit 浏览器(Chrome,Safari)现在使用的基数似乎超过了256。也许是216像歌剧那样?IE 和 Firefox 仍然使用256。

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

当前的 第四级工作草案很好地描述了 CSS 中的特异性:

特异性是通过比较三个组分的顺序来比较的: 具有较大 A值的特异性更具特异性; 如果两个 A值绑定,那么具有较大 B值的特异性更具特异性; 如果两个 B值也绑定,那么具有较大 C值的特异性更具特异性; 如果所有值绑定,两个特异性是相等的。

这意味着值 A、 B 和 C 是完全独立的。

15个类不会给你的选择器一个150的特异性分数,它会给它一个15的 B值。单个 A值就足以超过这个值。

作为一个比喻,想象一个由一个祖父母,一个父母和一个孩子组成的家庭。这可以表示为 一,一,一。如果父母有15个孩子,他们不会突然变成另一个父母(一,二,零)。这意味着父母比他们只有一个孩子(1115)要承担更多的责任。;)

同样的文件还说:

由于存储限制,实现可能对 ABC的大小有限制。如果是,则必须将高于该限制的值钳制到该限制,而不能溢出。

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

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

在浮士德的答案中给出的问题一直是大多数现代浏览器中的 修好了

我喜欢把特异性排名和奥运会奖牌榜进行比较(金牌第一的方法ーー首先以金牌数量为基础,然后是银牌和铜牌)。

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

也有相当好的专用计算器可用 给你。你可以把你的例子(# a 和。一。B.C.D.你好。F.克。哦。我。J.K.我。我。N.O)在那里看结果。

里约2016年奥运会奖牌榜的例子如下 enter image description here