oscarmarcelo oscarmarcelo - 1 month ago 3
CSS Question

Does :not() negation accept descendant selectors?

I've been using the

pseudo-class to style things without the need to override it with a second unnecessary declaration to undo the first one,
but now I came across a weird behaviour where Safari accepts descendant selectors within the
, but Chrome doesn't.

I used something like
a:not(.blue a)

I searched for answers, but I still don't fully understand the reason.

Are descendant selectors really allowed by the spec?

Here's a demo:

a:not(.blue a) {
color: red;

<div><a>this one should be in red</a></div>
<div class="blue"><a>this one shouldn't</a></div>



In Selectors Level 3, the answer would be NO. The :not() notation accepts only simple selectors.

6.6.7. The negation pseudo-class

The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument.

What is a simple selector?

From selector syntax:

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

Nothing about a descendant selector.

HOWEVER, in Selectors Level 4, :not() accepts complex selectors, which would include descendant combinators. Browser support is still quite weak for this specification.