Reputation: 43427
I have a list with groups in it, and use CSSOM to dynamically filter the contents using a text field. This is a way to implement a "search" using only CSS.
Unfortunately when the filter filters everything out, the group containers still remain visible. I'd need to also set display: none
onto them using CSS somehow, otherwise I need to add a bunch of JS to control them.
Is this remotely possible? I know this is a bit of a long shot, but is there a selector that can select elements whose children (fitting some selector) all must have a style selected on them?
Is it even possible if I greatly relax the constraints, where this might be a selector that selects elements whose children (fitting some selector) all must have a particular class?
Upvotes: 8
Views: 7905
Reputation: 5513
Actually, this is nowadays possible in CSS only with the :has selector, given it works as a parent selector. Also it is generally a good idea to use a class for hiding elements, which I have demonstrated below.
.container {
background-color: red;
padding: 2px;
}
@supports(selector(:has(div))) {
.container {
display: none
}
/* "unhides" all elements that contain at least one visible child element directly below */
.container:has(> :not(.invisible)) {
display: block;
}
}
.invisible {
/* display: none !important; */
background-color: yellow; /* for easier debugging instead */
}
<!-- This will be visible -->
<div class="container">
<h4>Should be visible:</h4>
<div class="invisible">Invisible 1</div>
<div class="invisible">Invisible 2</div>
<div class="invisible">...</div>
</div>
<!-- This will be hidden -->
<div class="container">
<div class="invisible">Invisible 1</div>
<div class="invisible">Invisible 2</div>
<div class="invisible">...</div>
</div>
<div class="container">
Inline text is getting ignored
<div class="invisible">Invisible 1</div>
<div class="invisible">Invisible 2</div>
<div class="invisible">...</div>
</div>
Mind the browser-support for :has
, so I've wrapped it in a @supports
clause.
Upvotes: 2
Reputation: 14012
No, it's impossible only via CSS:
:not([style*="display:none"]):not([style*="display: none"])
if you hide elements only using inline CSS.This can be solved only using pure JS loops and conditions or via jQuery selectors like .parent:not(:has(:visible))
.
Upvotes: 8