可以重复选择类型以增加特异性吗?

时间:2015-02-03 13:12:20

标签: css css-selectors specifications css-specificity

关于计算CSS特异性的spec州:(大胆的)

  

注意:允许重复出现相同的简单选择器   确实增加特异性。

因此,例如.class.class {}的特异性是.class {}的两倍 - DEMO

但是,关于术语'简单选择器'the spec,可以这样说:(大胆的)

  

简单的选择器是类型选择器或通用选择器   紧接着是零个或多个属性选择器ID   选择器或伪类,任何顺序。

因为规范说允许重复出现相同的简单选择器 - 这意味着你也可以重复type selectors

很明显,这样的事情不起作用:h1h1 { }

所以我尝试了这个:h1[]h1[] {} - 这也不起作用,

所以我想知道是否有办法做到这一点?

1 个答案:

答案 0 :(得分:12)

可以使用类型选择器来增加选择器的特异性,但不是常规的。其原因如下所述,但对于那些只是寻找替代方案的人来说,其中有两个。您可以在单个复合选择器中链接:not()包含类型选择器的伪类:

h1                      {} /* 1 type  -> specificity = 0-0-1 */
h1:not(_)               {} /* 2 types -> specificity = 0-0-2 */
h1:not(_):not(_)        {} /* 3 types -> specificity = 0-0-3 */
h1:not(_):not(_):not(_) {} /* 4 types -> specificity = 0-0-4 */

或者,如果您需要支持不支持:not()的旧版浏览器,则可以在复杂选择器的开头添加冗余类型选择器,例如htmlbody,虽然在这种情况下您受到的限制更多,因为您可能无法考虑所有元素:

h1                {} /* 1 type  -> specificity = 0-0-1 */
body h1           {} /* 2 types -> specificity = 0-0-2 */
html body h1      {} /* 3 types -> specificity = 0-0-3 */
html body tr > td {} /* 4 types -> specificity = 0-0-4, assumes every td is a child of tr */

毋庸置疑,这些被认为是特异性黑客攻击;与所有其他CSS黑客一样,如果有的话,请谨慎使用它们。


复合选择器在所有其他简单选择器之前最多只能有一个类型选择器。从Selectors 3(称之为一系列简单选择器):

  

序列的简单选择器是一组简单的选择器,它们没有被组合子分开。它始终以类型选择器或通用选择器开头。序列中不允许使用其他类型选择器或通用选择器。

Selectors 4

  

复合选择器 是一系列简单选择器,未被组合子分隔。如果它包含类型选择器或通用选择器,则该选择器在序列中排在第一位。序列中只允许使用一个类型选择器或通用选择器。

只有类型和通用选择器符合此规则;你可以结合并重复其他简单的选择器来提高特异性。也许这个规范可能会在关于计算特异性的部分提醒读者这一点,但我认为这绝对没必要。

这条规则的原因从未明确说明,但推断相当容易:

  • 请记住,类型选择器只包含一个标识符,例如h1。这与其他在语法中有自己的区别符号的简单选择器不同,例如ID(#),类(.),伪类(:),或属性选择器([])。如果没有办法单独解析它们,您将无法拥有多个连续类型选择器。

  • 即使你可以链类型选择器,例如,如果你之间有另一个简单的选择器,唯一可能的用途是作为特异性黑客,如问题,这意味着如果所有类型选择器都相同,您将只能使用它;没有其他类型选择器的组合可以工作。

    这是因为选择器假定文档语言将每个元素定义为只有一个元素类型。例如,在HTML中,h1始终为h1;它永远不会是任何其他类型的元素。要求同时包含h1p的元素的复合选择器永远不能匹配任何内容,因为[type=text][type=password]之类的内容永远不会匹配文档语言中的任何内容不支持重复属性。

但是,考虑到以上几点,仍然可以使用:not()伪类创建一个包含多个特定选择器的复合选择器:

  • :not()伪类的特殊性等于其参数。伪类本身不计算在内。这在第一个链接中提到。这意味着:not(h1)的特异性等同于h1 - 一种类型选择器。

  • 由于元素只能是一种类型,这意味着:not()与任何其他类型选择器都是保证匹配。

  • 由于复合选择器可能包含任意数量的伪类,因此您可以根据需要多次重复否定,即使否定都使用相同的类型选择器。

  • 由于选择器不关心选择器在任何特定文档语言的上下文中是否有意义,因此您可以使用类型选择器,保证永远不会匹配符合HTML文档中的任何元素,只要它满足类型选择器的Selectors语法。类型选择器只包含CSS标识符,因此任何CSS标识符都是公平游戏。包括_