0

我已经知道如何计算 CSS 的选择器特异性(规范中提到的 a/b/c/d)。:not()但是,我无法确定如何为伪类计算它。请参见以下示例:

input:not([type="text"],[type="password"],.someClass) {...}
input:not(#someId[type="text"]) {...}

假设它们都适用于一个元素,这两个是否应该计算为(0011),因此它们应该按照出现的顺序排列?或者是否应该:not()进一步单独计算伪类中的选择器,取决于哪个匹配,作为第二步来确定一个优先于另一个?

4

3 回答 3

4

假设它们都适用于一个元素,这两个是否应该计算为(0011),因此它们应该按照出现的顺序排列?还是应该:not()根据哪个匹配作为第二步来进一步单独计算伪类中的选择器,以确定优先于另一个的选择器?

如果您正在实施Selectors 3则根本不应该计算它们。如前所述,根据该规范,您的两个选择器都是无效的,因为它只定义:not()一次接受一个简单的选择器。

如果您将它们展开以便它们验证(按照此处给出的说明/示例),那么它们的特异性将按如下方式计算:

/* 2 attributes, 1 class, 1 type -> specificity = 0-3-1 */
input:not([type="text"]):not([type="password"]):not(.someClass)

/* 
 * 1 ID, 1 type        -> specificity = 1-0-1
 * 1 attribute, 1 type -> specificity = 0-1-1
 */
input:not(#someId), input:not([type="text"])

因为选择器 3 说

否定伪类中的选择器与其他选择器一样计算,但否定本身不计为伪类。

另外,针对您的评论:

诚然,根据规范,只有简单的选择器。但是有些浏览器支持多个浏览器。有些没有,有些后来放弃了。此外,即使使用像这样的简单选择器,您也可以编写相同的规则:input:not([type="text"]):not([type="password"]):not(.someClass)这更好并且也可以工作。这是否意味着它应该被计算为0031,那么呢?那些支持多个的呢,他们如何计算?

我所知道的唯一支持多个选择器的浏览:not()器是 Firefox 3.0,它之所以这样做是因为一个错误。Selectors 3不允许包含多个选择:not()器——仅在Selectors 4中引入,其特异性计算甚至还没有明确定义1,所以即使你试图实现 Selectors 4 (我严重怀疑你是),你会被卡住的。

我不清楚 Firefox 3.0 是如何通过其:not()选择器版本实现特异性的,我也没有它的副本可供测试,但我认为可以安全地假设它不再重要,因为它从来都不是预期的反正行为。好的,所以我选择了 Firefox 3.0 beta 1、3.0.0、3.0.18 和 3.1 beta 1,但它们都没有重现这种行为。所以你有它。


1 请注意,当前的 2013 ED 和 2011 FPWD 一致认为 的特异性:not()与其最具体的论点相同,但这可能会在未来发生变化。

于 2013-04-26T03:03:21.380 回答
1

逻辑意图

下面是问题中最初发布的 CSS 选择器的细分。这是试图总结如何使用有效的 CSS 来表达这两个 CSS 规则(由@thgaskell 和@BoltClock 发起的讨论)。我将把具体问题留给其他海报。

第一条规则

input:not([type="text"],[type="password"],.someClass) {}

这是 CSS3 中的非验证选择器,目前可能不被任何已知浏览器支持。

选择器的逻辑意图是!(a or b or c),相当于!a and !b and !c. 对于 CSS 选择器,逻辑and操作需要链接,可以表示为:not(a):not(b):not(c).

因此,第一条规则可以用有效的 CSS 表示如下:

input:not([type="text"]):not([type="password"]):not(.someClass) {}

第二条规则

input:not(#someId[type="text"]) {}

这是 CSS3 中的非验证选择器,目前可能不被任何已知浏览器支持。

选择器的逻辑意图是!(a and b),相当于!a or !b. 对于 CSS 选择器,逻辑or操作需要使用多个选择器(每个操作数一个选择器),可以表示为:not(a), :not(b).

因此,第二条规则可以用有效的 CSS 表示如下:

input:not(#someId), input:not([type="text"]) {}

概括

逻辑and运算需要链接每个操作数。

.a.b {}                /* Matches elements with both classes  */
                       /*     (a and b)                       */

:not(.a):not(.b) {}    /* Matches elements with neither class */
                       /*     (!a and !b) == !(a or b)        */

逻辑or操作需要使用多个选择器(每个操作数一个选择器)。

.a, .b {}              /* Matches elements with either class              */
                       /*     (a or b)                                    */

:not(.a), :not(.b) {}  /* Matches elements that don't have both classes   */
                       /* (elements with none or only one of the classes) */
                       /* (aka: not both, nand, alternative denial        */
                       /*     (!a or !b) == !(a and b)                    */
于 2013-04-26T09:50:55.457 回答
0

规范(W3C Selectors Level 3)非常清楚地表明伪类与类相同。

一些在主要浏览器中玩弄 jsfiddle 表明您是正确的(在您的评论中),并且

 input:not([type="text"]):not([type="password"]):not(.someClass) {border:3px solid red}

...将是 0.0.3.1。稍后在样式声明中需要 3 个类名来否决上述选择器。

鉴于:

<input value="X" class="Y Z" id="myId"/>

您不能仅使用以下方法覆盖上述选择器:

input.Y.Z{border:3px solid pink;}

http://jsfiddle.net/mhfaust/SxavM/1/

更新BoltClock 是对的。规范指出“否定伪类中的选择器与其他任何类型的选择器一样计算,但否定本身不计为伪类。” 因此,在本例中,由于其中的每个选择器:not() 都是类名或伪类,因此特异性保持为 0.0.3.1

于 2013-04-26T01:30:08.730 回答