Reputation: 3461
I have a part of my HTML that is similar to the one below, and I must select only the elements that do not have any ancestors with a specified class. The project I work on is pretty big and I think I should not post here all the code, I think that would be beyond the purpose of StackOverflow.
What I want is filtering the elements by all their ancestors, not only by their parents. I have tried this:
// This colors two of the <span> elements instead of one. It colors the ".a > .b" <span> and this behavior seems wrong to me.
$(":not(.a) .b:not(.a)").css("color", "red");
// This call only colors the border of the ".b" <span> which, I think, is the correct behavior and should be the behavior of the call above.
$(":not(.a) > .b:not(.a)").css("border-color", "blue");
span {
border: 0.1rem solid gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a">
<span class="b">.a > .b</span> <!-- Why does this <span> element become red? -->
<span class="a b">.a > .a.b</span>
</div>
<div>
<span class="b">.b</span>
<span class="a b">.a.b</span>
</div>
I have put the code above in this JSFiddle. I have tested the two selectors using the document.querySelectorAll
function without jQuery and the behavior is the same.
Thank you very much! :-)
Upvotes: 1
Views: 185
Reputation: 723448
Do you mean to select .b
elements that
.a
, and.a
?Then this is only doable with jQuery (learn more):
$(".b:not(.a, .a *)")
If you need to do this in CSS, you can either add a class using jQuery with the above selector, or use an override:
.b {
/* Style all .b elements */
}
.a .b, .a.b {
/* Override the previous rule */
}
Upvotes: 1
Reputation: 46323
:not(.a) .b:not(.a)
Selects all elements with class b, but without class a, that has any ancestor without class a, for example, <body>
& <html>
.
:not(.a) > .b:not(.a)
Selects all elements with class b, without class a, that hasn't a direct parent with class a.
Upvotes: 3