17

Is it possible to have nested values inside the :not selector? For eg:

:not(div > div)

Whenever I tried it, it does not seem to work. Perhaps you need to use it another way which I have not figured out? So far, in all the examples I see, you can only use one value inside this selector.

1
  • div > div div should be the case what you are looking for.. right? Commented Feb 14, 2014 at 4:56

2 Answers 2

21

:not() only accepts one simple selector at a time; this is mentioned in the Selectors 3 spec:

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.

The simple selectors in your example would be the two div tokens that you have. Other simple selectors include class selectors, ID selectors, attribute selectors and pseudo-classes. It does not accept more than one simple selector, nor does it accept combinators like > or space.

Depending on which elements you're trying to select exactly, there may not be a way to exclude div > div:

  • If you only want to select elements that are children of a div, that are themselves not div, use this instead:

    div > :not(div)
    
  • If you only want to select div elements whose parent element is not a div, use this instead:

    :not(div) > div
    

If you want to use this negation by itself, selecting all other elements, then there isn't a way using just a selector.

The only other viable workaround in CSS that I can think of is to apply styles to the elements you want without the :not() expression, then undo them for div > div. This works for any set of elements you're trying to target; the disadvantage is that not all properties can be easily reset.

Alternatively, if you're using jQuery, which does support :not(div > div) unlike the CSS version, you can place the selector in a script and, for instance, have jQuery apply a class name to those elements then target that class in your CSS.

Sign up to request clarification or add additional context in comments.

2 Comments

If one could live with a comma in their selector, :not(div), :not(div) > div might work to select everything that doesn't match div > div.
@cHao: That seems so obvious to me now, I really have no idea how I missed it. Thanks!
4

It should work now thanks to Selectors Level 4 which allows :not() to take a list of complex selectors.

You can now also nest :not()... like :not(:not()) which wasn't allowed in Selectors Level 3. Not sure why you'd want to do that but you can.

2 Comments

I guess I am blind, can you link to the specific part or how you arrived at that? I did notice it working too which caught me off guard.
@KerryJohnson - see w3.org/TR/selectors-4/#negation . There is no mention of this limitation. In the old level 3 spec, at w3.org/TR/selectors-3/#negation , it explicitly says "Negations may not be nested".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.