CSS selector for something not inside something else
You can use the Child Combinator Selector >
to specify direct children:
.select-inside-this :not(.not-inside-this) .select-this,
.select-inside-this > .select-this {
/* style here /*
}
This selects any .select-this
element which is not a descendent of any .not-inside-this
element and also selects .select-this
elements which are direct children of .select-inside-this
elements.
body > .select-inside-this :not(.not-inside-this) .select-this,
body > .select-inside-this > .select-this {
color: red;
}
<div class="foo">
<div class="select-inside-this">
<div class="not-inside-this">
<div class="one select-this">
This should not be selected
</div>
</div>
</div>
</div>
<div class="select-inside-this">
<div class="two select-this">
This should be selected
</div>
</div>
<div class="three select-this">
This should not be selected
</div>
:not(.not-inside-this)
and *:not(.not-inside-this)
with the *
are equivalent; in the case of the former, the universal selector is implied. See the spec.
It is currently not possible to construct a CSS selector that matches elements that are not descendants of specific elements for the reasons given in the following questions:
- CSS negation pseudo-class :not() for parent/ancestor elements
- Is the CSS :not() selector supposed to work with distant descendants?
The selector
.select-inside-this :not(.not-inside-this) .select-this
matches .select-this
elements that are descendants of some element that is not .not-inside-this
, which in turn is a descendant of .select-inside-this
. It does not match .select-this
elements that are not descendants of .not-inside-this
within .select-inside-this
.
This means, first off, that your selector will incorrectly match the following:
<div class="select-inside-this">
<div class="bar">
<div class="not-inside-this">
<div class="select-this"></div>
</div>
</div>
</div>
... because one of the ancestors of .select-this
, .bar
, is :not(.not-inside-this)
.
Additionally, this implies at least three levels of nesting (though it could be more). In your example, there are no other elements between .two.select-this
and its containing .select-inside-this
, so it will never match that element. This is why James Donnelly suggests adding .select-inside-this > .select-this
to account for that particular case.
However it is still not possible to write a single complex selector using descendant combinators to match elements without a specific ancestor. The only way is to repeat the child combinator method with as many :not(.not-inside-this)
as necessary, but this requires that you account for all possible cases. If you can't do that, then you're out of luck with CSS selectors.