I have some nested elements like this:
<div class="foo"> <div class="select-inside-this"> <div class="not-inside-this"> <div class="one select-this"></div> </div> </div> </div> <div class="select-inside-this"> <div class="two select-this"></div> </div> <div class="three select-this"></div>
I want to select all .select-this
which are inside .select-inside-this
but not those which are wrapped in .not-inside-this
. So in the end, i should be able to select only two.select-this
from the above code. The CSS I've tried but did not work:
.select-inside-this :not(.not-inside-this) .select-this { /* style here /* }
or:
.select-inside-this *:not(.not-inside-this) .select-this { /* style here /* }
Any workaround here?
I don't want to use JavaScript here. I need pure CSS3 solution.
EDIT: I don't want to use direct child (>
) selector. As I've asked, I want to select all those element from any level just without the exception wrapper.
In CSS, to exclude a particular class, we can use the pseudo-class :not selector also known as negation pseudo-class or not selector. This selector is used to set the style to every element that is not the specified by given selector. Since it is used to prevent a specific items from list of selected items.
You need to Simply use the :not pseudo class to pick the right child. This time you put an element selector, that's an anti pattern.
:not() The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class. /* Selects any element that is NOT a paragraph */ :not(p) { color: blue; }
Nesting Selector: the & selector. When using a nested style rule, one must be able to refer to the elements matched by the parent rule; that is, after all, the entire point of nesting. To accomplish that, this specification defines a new selector, the nesting selector , written as & (U+0026 AMPERSAND).
: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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With