如何计算CSS特异性中的点


124

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

它指出,特异性是CSS的得分系统。它告诉我们元素值1分,类值10分,ID值100分。最重要的是,这些点是合计的,总数就是选择者的特异性。

例如:

身体 = 1点
身体.wrapper = 11点
身体.wrapper#容器 = 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


Answers:


137

佩卡的回答几乎正确的,并且可能是思考该问题的最佳方法。

但是,正如许多人已经指出的那样,W3C CSS建议指出:“将三个数字abc(在基数较大的数字系统中)连接起来具有特殊性。” 因此,我的极客只需要弄清楚这个基数是多少。

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

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

因此,实际上有一个“点系统”,但它不是以10为基础,而是以256为基础。这是它的工作方式:

(2 82或65536,乘以选择器中ID的数量
+(2 81或256,乘以选择器中类名称的数量
+(2 80或1,乘以tag的数量-选择器中的名称

这对于进行信封式练习来传达概念不是很实际。
这可能就是有关该主题的文章一直使用10进制的原因。

***** [Opera使用2 16(请参阅karlcow的注释)。其他一些选择器引擎使用无穷大 -实际上是无分制(请参见Simon Sapin的评论)。

2014年7月更新:
正如Blazemonger在当年早些时候指出的那样,Webkit浏览器(chrome,safari)现在使用的基数高于256。也许2 16,像Opera?IE和Firefox仍使用256。


34
重要提示:请注意,数字256不在规范中。因此,此答案描述了(公认有用的)实现细节。
马特·芬威克

6
正如@MattFenwick所说,不仅规范中没有256,而且在实现上也有所不同。在Opera中,它显然更大。在WeasyPrint和cssselect中,它是“无穷大”:我使用整数元组而不是单个整数。
西蒙·萨平

3
@浮士德歌剧使用16位而不是8位
karlcow 2012年

4
老实说,这个答案比Pekka的答案更具实用性。基本上是@Matt Fenwick所说的:您要描述的是该规范的实际实现。这样做是有缺陷的,但无论是作者还是实施者,都不应做任何事情。
BoltClock

7
256在当前版本的Webkit(Chrome和Safari)中似乎不足,进一步强调了@MattFenwick的观点。
Blazemonger,2014年

28

好问题。

我不能肯定地说-我设法找到的所有文章都避免使用多个类的示例,例如在这里 -但我假设在比较类选择器和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时如何将其转换为十进制。


那是因为它在.o和.a .b等之间,因此它将统一考虑它们。但是在一个ID和一个类之间,例如:.a和#a,该ID总是会过载。(我假设)仅当没有更强大的属性时才在类之间进行计数。例如,类将超过元素,而id将超过类。
Sphvn 2010年

@Ozaki这也是我的假设,但与OP关于积分系统的说法相矛盾。必须有更多的游戏。我想看看它背后的规则。
Pekka 2010年

只是意识到我们两个人得出了相同的结论。优秀作品!
山姆

5
对于数学方面,我们可以在此处以16为底进行运算(因为单个数字都不超过15)。因此0,1,0,0 = 0100h = 256 0,0,15,0 = 00f0h = 240 256> 240,因此id选择器获胜。
马修·威尔逊

1
是的,您可以认为特异性计算是在基数较大的数字系统中完成的。我认为术语“连接”(在规范中也使用)是更好的描述。(这里来自回答一个新问题,事实证明是这个问题的重复,
请参

9

当前的选择器第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

自从浮士德的答案中给出的问题已在大多数现代浏览器中得到解决


8

我目前正在使用《CSS Mastery:高级Web标准解决方案》这本书。

第16页第1章说:

为了计算规则的具体程度,为每种选择器分配了一个数值。然后,通过将每个选择器的值相加来计算规则的特异性。不幸的是,特异性不是以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]比高基数系统更大。


4

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

它也适用于您的问题(一个特异性组中的选择器数量众多)。特异性分别考虑各组。在现实世界中,很少有超过十个选择器的情况)。

酒店还设有相当不错的特异性计算器这里。您可以将示例(#a和.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o)放在此处,然后查看结果。

里约2016年奥运会奖牌表示例如下 在此处输入图片说明


3

我认为博客的解释不正确。规格在这里:

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

类选择器的“点”加起来比“ id”选择器重要。就是那样行不通。


就像我在回答中说的那样。^^但是,如果您拥有更多相同类型的元素(元素,类,id),则确实会有所不同。但这很明显,如果第5点说红色,第3点说蓝色,则Ima变红。
Sphvn 2010年

在CSS2和CSS2.1之间,围绕专用性的措词可能并没有太大变化,但是在以后的讨论中,您确实应该指向CSS2.1规范,因为它完全取代了CSS2,而CSS2在发行时通常就被破坏了。
罗宾·惠特尔顿

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/

“如果5件事说红色,而3则说蓝色,那么伊马会变红”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.