Calculating CSS selector specificity for: not () pseudo-class

I already know how to calculate selector specificity for CSS (a / b / c / d mentioned in the specs). However, it's hard for me to figure out how to compute it for the pseudo-class :not() . See the following example:

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

Assuming both of them apply to the same element, should these two be calculated as (0011), and therefore should they be ordered according to the order of appearance? Or should we additionally select selectors inside the pseudo-class :not() separately, depending on which one matches, as a second step to determine who takes precedence over the other?

0
source share
3 answers

Assuming both of them apply to the same element, should these two be calculated as (0011), and therefore should they be ordered according to the order of appearance? Or should the selectors inside the :not() pseudo-class be additionally evaluated separately, depending on which one corresponds to the second step to determine who takes precedence over the other?

If you are implementing Selectors 3 , they should not be considered at all. As already mentioned, both of your selectors are invalid according to this specification, as it only defines :not() to accept one simple selector at a time.

If you arrange them so that they check (following the instructions / examples given here ), then their features will be calculated as follows:

 /* 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"]) 

Because Selectors 3 say :

Selectors within the pseudo-class of negation are counted like any other, but negation itself is not considered a pseudo-class.

Also, in response to your comment:

True, according to the specifications, only simple selectors. But some browsers support several. Some of them do not, and some later discarded them. In addition, you can write the same rule even with simple selectors like this: input:not([type="text"]):not([type="password"]):not(.someClass) , which is better and works. Does this mean that it should be calculated as 0031? What about those who support multiple, how do they calculate?

The only browser I know of has ever supported multiple selectors in :not() is Firefox 3.0, and it does this because of an error. Selectors 3 never allowed :not() contain several selectors that are introduced only in Selectors 4 , for which the specificity calculation was not even clear but even 1 therefore, even if you tried to implement Selectors 4 (which I seriously doubt you) You will be stuck.

I don’t understand how Firefox 3.0 implemented the specification with its selector version :not() , and I don’t have a copy for testing, but I think it’s safe to assume. So, I chose Firefox 3.0 beta 1, 3.0.0, 3.0 .18 and 3.1 beta 1, and none of them reproduce this behavior at all. So you have it.


1 Note that both the current 2013 ED and the 2011 FPWD are consistent with the statement that the specification :not() is equal to the characteristic of its most specific argument, but this may change in the future.

+4
source

Logical intention

The following is a breakdown of the CSS selectors originally posted in the question. This is an attempt to generalize how both CSS rules can be expressed using proper CSS (discussion started with @thgaskell and @BoltClock). I will leave a question about the specifics of other posters.

First rule

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

This is an invalid CSS3 selector that is currently not supported by any known browsers.

The logical intent of the selector is !(a or b or c) , which is equivalent to !a and !b and !c For CSS selectors, the logical and operation requires a chain, which can be expressed as :not(a):not(b):not(c) .

Thus, the first rule can be expressed in real CSS as follows:

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

Second rule

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

This is an invalid CSS3 selector that is currently not supported by any known browsers.

The logical target of the selector !(a and b) , which is equivalent to !a or !b For CSS selectors, the logical or operation requires the use of several selectors (one selector for each operand), which can be expressed as :not(a), :not(b) .

Thus, the second rule can be expressed in real CSS as follows:

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

Summary

The logical operation and requires a chain of each operand.

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

Logical operation or requires the use of multiple selectors (one selector for each operand).

 .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) */ 
+1
source

The spectrum ( W3C Selectors Level 3 ) is pretty clear that pseudo-classes are considered the same as classes.

Some games with jsfiddle in main browsers show that you are right (in your comment) and specificity for

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

... will be 0.0.3.1. It takes 3 class names in a style declaration, which comes later to override the selector above.

Given:

 <input value="X" class="YZ" id="myId"/> 

You cannot override the selected selector with:

 input.YZ{border:3px solid pink;} 

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

update . BoltClock is right. The specification states that "Selectors within a pseudo-class of negation are considered like any other, but negation itself is not considered a pseudo-class." Since each selector inside :not() in this example is a class name or pseudo-class, the specificity remains 0.0.3.1

0
source

Source: https://habr.com/ru/post/1479783/


All Articles