是否可以重复类型选择器以增加特异性? [英] Can type selectors be repeated to increase specificity?

查看:129
本文介绍了是否可以重复类型选择器以增加特异性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

规范说明了计算CSS特异性的方法:(bold mine)


注意:允许重复出现相同的简单选择器,并且
可增加特异性。

$ b $因此,例如 .class.class {} 具有两倍的特异性。 class {} - DEMO



但是,关于简单选择器规范有这个说法:(bold mine)


一个简单的选择器是类型选择器 b $ b后紧跟着零个或多个属性选择器,ID
选择器或伪类。按照任何顺序。


因此,由于规范说重复出现相同的简单选择器是允许的 - 这意味着您可以重复

很明显这样的东西不会工作: h1h1 {}



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



所以我想知道是否有办法做这个?

解决方案

使用类型选择器可以增加选择器的特异性,但不是常规的。原因在下面解释,但对于那些只是寻找一种替代,那里有两个。您可以在单个复合选择器中链接:not()伪类包含类型选择器:

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

或者,如果您需要支持旧版浏览器, t支持:html 和 body,可以添加冗余类型选择器到复杂选择器的开头,尽管在这种情况下你的限制远远不够,因为你可能无法计算所有元素:

  h1 {} / * 1 type  - > specific = 0-0-1 * / 
body h1 {} / * 2 types - > specific = 0-0-2 * /
html body h1 {} / * 3 types - > specific = 0-0-3 * /
html body tr> td {} / * 4 types - > specific = 0-0-4,假设每个td是tr *的子项/

不用说,这些被认为是特异性攻击;






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


一个简单选择器序列是一个不由组合器分隔的简单选择器链。它始终以类型选择器或通用选择器开头。在序列中不允许使用其他类型选择器或通用选择器。


并且选择器4


复合选择器 是不由组合器分隔的一系列简单选择器。如果它包含类型选择器或通用选择器,则该选择器在序列中位于第一位。


只有类型和通用选择器受此规则约束;您可以组合和重复其他简单选择器以增加特异性。也许规范可以提醒读者关于计算特异性的部分,但我不认为这是绝对必要的。



这条规则的原因从来没有说明显然,但很容易推断出:




  • 请记住,类型选择器只包含一个标识符,例如 h1 。这不像其他在语法中有自己的区别符号的简单选择器,例如ID(),类(),伪类()或属性选择器( [] )。


  • 即使您可以链接,您仍然无法连接多个连续的类型选择器类型选择器,例如,如果你在它们之间有另一个简单的选择器,唯一可能的用途是作为一个特殊的hack,如问题所述,这意味着你只能使用它,如果所有的类型选择器是相同;没有其他类型选择器的组合可以工作。



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




但是,考虑到上述要点,仍然可以创建一个包含多个类型选择器的复合选择器, :not()伪类别:




  • :not()伪类等于其参数。伪类本身不计数。这在第一个链接中提到。这意味着:not(h1)相当于 h1 - 一个类型选择器。

    / li>
  • 由于一个元素只能有一个类型,这意味着:not()


  • 由于复合选择器可能包含任何数量的伪类,因此您可以根据需要重复否定次数,即使否定


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



The spec states regarding calculating CSS specificity: (bold mine)

Note: Repeated occurrences of the same simple selector are allowed and do increase specificity.

So for example .class.class {} has twice the specificity than .class {} - DEMO

However, regarding the term 'simple selector' the spec has this to say: (bold mine)

A simple selector is either a type selector or universal selector followed immediately by zero or more attribute selectors, ID selectors, or pseudo-classes, in any order.

So since the spec says that repeated occurrences of the same simple selector are allowed - this would imply that you could repeat type selectors as well.

Well quite obviously something like this won't work: h1h1 { },

so I tried this: h1[]h1[] {} - which doesn't work either,

so I'm wondering if there is a way to do this?

解决方案

It is possible to increase the specificity of a selector using type selectors, but not conventionally. The reason for this is explained below, but for those who are simply looking for an alternative, there are two of these. You can either chain :not() pseudo-classes containing type selectors in a single compound selector:

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 */

Or, if you need to support legacy browsers that don't support :not(), you can add redundant type selectors such as html and body to the beginning of a complex selector, although you are far more limited in this case as you may not be able to account for all elements:

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 */

Needless to say, these are considered specificity hacks; as with all other CSS hacks, use them sparingly, if at all.


A compound selector may only have at most exactly one type selector preceding all other simple selectors. From Selectors 3 (which calls this a sequence of simple selectors):

A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.

And Selectors 4:

A compound selector is a sequence of simple selectors that are not separated by a combinator. If it contains a type selector or universal selector, that selector comes first in the sequence. Only one type selector or universal selector is allowed in the sequence.

Only type and universal selectors are subject to this rule; you may combine and repeat other simple selectors to increase specificity. Perhaps the spec could have reminded the reader about this in the section on calculating specificity, but I don't think it's absolutely necessary.

The reason for this rule is never stated explicitly, but it is fairly easy to deduce:

  • Remember that a type selector consists of simply an identifier, e.g. h1. This is unlike other simple selectors which have their own distinguishing symbols in the grammar, such as an ID (#), a class (.), a pseudo-class (:), or an attribute selector ([]). You would not be able to have multiple consecutive type selectors without a way to parse them separately.

  • And even if you could chain type selectors, for example if you had another simple selector between them, the only possible use for this would be as a specificity hack, as described in the question, which means you would only be able to use it if all the type selectors were the same; no other combination of type selectors could work.

    This is because Selectors assumes that the document language defines every element to have exactly one element type. For example, in HTML, an h1 is always an h1; it can never be any other type of element. A compound selector asking for an element that is both an h1 as well as a p can never match anything, for the same reason something like [type=text][type=password] can never match anything in a document language that does not support duplicate attributes.

However, with the above points in mind, it is still possible to create a compound selector that contains more than one type selector for specificity — by using the :not() pseudo-class:

  • The specificity of a :not() pseudo-class is equal to its argument. The pseudo-class itself is not counted. This is mentioned in the first link. This means the specificity of :not(h1) is equivalent to h1 — one type selector.

  • Since an element can only be of exactly one type, this means :not() with any other type selector will be a guaranteed match.

  • Since a compound selector may include any number of pseudo-classes, you can repeat the negation as many times as necessary, even if the negations all use the same type selector.

  • And since Selectors doesn't care if a selector makes sense in the context of any particular document language, you can use a type selector that is guaranteed to never match any element in a conforming HTML document as long as it satisfies the Selectors grammar for a type selector. A type selector consists of nothing but a CSS identifier, so any CSS identifier is fair game. Including _.

这篇关于是否可以重复类型选择器以增加特异性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆