G'day all,
I'm once again struggling with :not(), it does not behave as I expect it to. So I created the below fiddle to allow us to start at the same point.
The Question
How do I make the middle grouping of links (under the Blue text) all blue in this example using the :not() selector.
Reference Code
Example Preface: This is a simplified example. I'm not looking for someone to say "Dude, you can move the .red class and it'll work like you want. No :not() at all." ... I'm trying to work out :not() here.
Testing example - https://jsfiddle.net/2tbwkcyg/1/
The structure is
<div> <!-- control group | green -->
Green<br>
<nav>Nav: <a href="/">Testing Link</a> | <a href="/">Testing Link</a></nav>
<div>Div: <a href="/">Testing Link</a> | <a href="/">Testing Link</a></div>
Direct: <a href="/">Testing Link</a> | <a href="/">Testing Link</a>
</div> <!-- /control group | green -->
<div class="red">
<div class="blue">
Blue<br>
<nav>Nav: <a href="/">Testing Link</a> | <a href="/">Testing Link</a></nav>
<div>Div: <a href="/">Testing Link</a> | <a href="/">Testing Link</a></div>
Direct: <a href="/">Testing Link</a> | <a href="/">Testing Link</a>
</div> <!-- /blue -->
<div>
Red<br>
<nav>Nav: <a href="/">Testing Link</a> | <a href="/">Testing Link</a></nav>
<div>Div: <a href="/">Testing Link</a> | <a href="/">Testing Link</a></div>
Direct: <a href="/">Testing Link</a> | <a href="/">Testing Link</a>
</div>
</div> <!-- /red -->
while the (relevant) CSS is
a{color:green}
.blue a{color:blue}
.red :not(.blue) a{color:red}
Expected Results
Due to that last line in the CSS, I'm expecting the middle group of links to be blue, because - it's in the .red section, and they are within the .blue class.
Therefore, the expected result is:
- Six Green links
- Six Blue links
- Six Red links that is, three x two of each colour.
Actual Results
But with that CSS, I get:
- Six Green links
- Four Red links + Two Blue links
- Six Red links
I have tried many of the solutions & suggestions here on StackOverflow, such as wrapping the selector inside the :not() with double quotes, using * before :not() and the like. But none of that appears to work. (None of which are noted on the definition btw: https://developer.mozilla.org/en-US/docs/Web/CSS/:not )
Point of Interest: I've just put in another row (the Direct one), and it seems to imply that the :not() part must immediately precede the next element selected - as they show as blue. While the ones another level down do not.
Browser Compatibility
All major browsers are on the table for this one.
I.E., Opera Mobile, QQ and Baidu Browsers are not considerations.
Thanks in advance! :)
-- EDIT --
@robby-cornelissen pointed out that on the MDN article I linked above it says:
This selector only applies to one element; you cannot use it to exclude all ancestors. For instance,
body :not(table)a will still apply to links inside a<table>, since<tr>will match with the:not()part of the selector.
Which is sad. Because that's what I wanted. I wanted to have a negating class/selector somewhere between the defining class/selector and the subject, to prevent the rules applying - rather than setting / overriding with multiple lines.
@kmoser did however manage to make this sing a little using a >. It seems that if you "bind" the :not() to an immediate parent it works and overrides :not()'s implied relationship with the immediate child.
.red>:not(.blue) a{color:red}seems to give the results you're looking for. See Fiddle here