10

大粗体大写锁定 TL;DR:

我知道如何确定选择器的特异性,我认为它使用了有缺陷的假设,我可以用有效的集合理论关系来支持我的愤怒,请不要回应解释 W3 计算规则的特异性,请阅读问题<-阅读。

这困扰了我一段时间,当我为一些类似于下面的 HTML 编写样式时:

...
<div id="outer">
    <span id="inner"></span>
    <span></span>
    ...
</div>
...

为什么特异性规则会使选择器“#outer span”比“#inner”更具体?ID 是唯一的,所以当我说“#inner”时,我只能指代一个元素,为什么它不那么具体?我了解确定特异性的规则,我只是想知道这是故意的还是偶然的,以及是否有人知道我如何向编写 css 标准的人提出这个问题。

我应该注意,我知道我可以使用 #outer #inner 来确保最大的特异性,但这似乎首先违背了 ID 的目的。当我编写模板并且我不确定一个 ID 是否会在另一个 ID 中时,这也是一个有问题的解决方案。我不是在寻找解决方法,只是在寻找理论答案。

我的问题是理论,完全基于集合逻辑。尽管我的想法是,如果您为 n 个可能项目中的 1 个项目定义规则,那不是尽可能具体吗?为什么 CSS 选择器的创建者会制定一个可以定义 n 个可能项目中的 m 个项目的规则,其中 m 是 n 的子集作为更具体的规则?

我的想法是,#id 相当于按名称识别 1 个项目,而 #id elm 将通过名称与项目的关系来识别一个组。将命名项目称为比具有命名关系的未命名组更不具体是完全违反直觉的。

4

4 回答 4

9

我认为“为什么”的想法更多的是“代际”或“权威”的观点。如果#Parent(任何一代人)说我所有符合资格“x”的孩子(在你的情况下,span)都将获得“y”的继承权(无论css属性),那么个人#Child想要什么并不重要,#Parent如果父母另有说明,则需要获得它的权限。

编辑时添加:内联style将是叛逆的孩子,以及!important镇压的父母。编辑:我保留这个是为了幽默,但我不认为它反映了这个想法以及我后来在下面的陈述。

在评论中添加了对问题的编辑:鉴于:

#outer span ...
#inner (which is a span element)

然后为了帮助确保#inner 选择,我建议:

body span#inner (*edit:* just span#inner works *edit:* if defined later)

或给 body 一个 id 和

#bodyId #inner

当然,这些仍然可以被覆盖。涉及的“世代”越多,由于世代共识而改变行为就越困难(如果曾祖父和祖父以及父母都同意,那么孩子很可能不会做自己的事) .

鉴于 此 HTML:

<div id="grandparent">
  <div id="parent">
    <div id="child"></div>
  </div>
</div>

我之前说过“#parent div有更大的权威#grandparent div。两者都有代际权威,实际上,一个'平等'的代际权威,但首先是'更近'的一代”获胜。错误在于世代“更接近”并不重要,而是最后被授予权威。给定相同的权威权力,自己指定的最后一个是获胜者。

我相信我仍然可以坚持这种说法:考虑到这一点,像 #child[id] 这样的选择器(其重要性超过了之前的两个选择器)将其属性视为权限,以获得更大的权限来统治自己所控制的东西。拥有 # 已经赋予了它权限,但如果早一代还带有另一个授予更多权限的选择器,则不足以覆盖早一代的 #。

因此,如果它是最后一个获得权威 [add this]#grandparent div,但不是#child因为它增加了更大的权威来统治自己。如果选择性相同,则最后一个被授予权限的人获胜。div#child #child[id][id]#child

同样,style设置样式属性本身的属性实际上更像是授予统治自己的至高无上的权力,假设更多的“ !important”不会将其带走。

作为一个总结性陈述来回答“为什么”它是这样的(并且不符合“集合”理论),我相信这不是关于准确性甚至是特异性(尽管这是使用的术语),正如人们所期望的那样#ChildsName成为这件事的最终唯一发言权,因为没有什么更具体的需要说的了。然而,尽管文件可能没有这样说明,但“选择性”实际上是基于授予权限而构建的。谁拥有最多的“权利”来统治元素,并给予“领带”,谁是最后一个被授予这些权利的人。

于 2010-07-22T18:07:44.750 回答
3

因为#outer span同时具有 ID 选择器和元素选择器。该元素选择器使其重量超过#inner.

前者的意思是“选择在 ID 的任何元素中找到的任何元素outer”。
后者的意思是'选择任何ID 为'的元素inner。它不知道#inner您的 HTML 文档中的位置,因此特异性较低。

也许你可以尝试#outer #innerspan#inner试试吧#outer span#inner

于 2010-07-22T17:33:35.153 回答
1

如何

W3C 计算特异性的规则

  • 计数 1 如果声明来自是“样式”属性而不是带有选择器的规则,否则为 0 (= a) (在 HTML 中,元素的“样式”属性的值是样式表规则。这些规则没有选择器,所以 a=1、b=0、c=0 和 d=0。)
  • 统计选择器中 ID 属性的数量(= b)
  • 计算选择器中其他属性和伪类的数量(= c)
  • 计算选择器中元素名称和伪元素的数量(= d)

特异性仅基于选择器的形式。特别是,“[id=p33]”形式的选择器被算作属性选择器(a=0, b=0, c=1, d=0),即使 id 属性被定义为“ID " 在源文档的 DTD 中。

连接四个数字 abcd(在具有大基数的数字系统中)给出了特异性。此外,当规则具有相同的特异性时,最后一个获胜。

例子

  • 外跨度:a=0, b=1, c=0, d=1 --> 101

  • 跨度#inner: a=0, b=1, c=0, d=1 --> 101
  • div#outer span#inner: a=0, b=2, c=0, d=2 --> 202

尝试重新排列规则 1 和 3:http: //jsfiddle.net/Wz96w/

为什么

我的想法是#inner 没有指定一个独特的元素。虽然每页只有 1 个元素,但该 ID 可能是另一页上完全不同的元素。

一页:

<div id="outer">
  <div id="inner"> ... </div>
</div>

另一个页面:

<ul id="outer">
  <li>main1
    <ul id="inner">
      <li>sub1</li>
      <li>sub2</li>
    </ul>
  </li>
  <li>main2</li>
</ul>

虽然,我不会这样编码。我认为它解释了为什么添加元素 ( ul#outervs. #outer) 值得额外的特殊性。

对于后代的观点,我正在为您的标记可视化 DOM。该规则#outer span的路径长度大于#inner。因此,在这种情况下,它指定了一个更具体的子树,因此应该授予它更多的特异性(并且#outer #inner li应该 [is] 价值超过#inner li)。

于 2010-07-22T18:00:47.447 回答
0

对我来说,我完全基于意见,这是预期的“自然”行为。

考虑一下:

你知道 CSS 特异性是如何计算的,从那个公式我们知道它#outer span比 更具体#outer,这对于整个 CSS 正常工作是必要的,而且它是有道理的。#outer span也比 更具体#inner,这在样式表的域中也是合乎逻辑的 (#inner只是一个 ID,并且#outer span是一个 ID 加一个元素,所以如果我们只是查看样式表,为了对它们进行排名,必须越合格更加详细一些)。

这里发生的情况是,您正在应用 HTML 标记的上下文,并说“嗯,这没有意义”。为了使事情按您期望的方式工作,浏览器必须考虑以下内容:

  • <span id="inner">是里面<div id="outer">
  • 样式表规则#outer span#inner应用
  • 该规则#outer span#inner
  • 可是等等!<span id="inner">在里面<div id="outer">,所以忽略基于样式表的计算并声称#inner更具体

最后一步使确定过程完全基于 HTML 的结构,这使得仅根据 CSS 定义特异性是不可能的。我个人认为这会使整个过程更加复杂且难以定义,但您可能不同意。

于 2010-07-22T18:31:15.547 回答