2

Question: Is there in 2018 any CSS construct that would hide divs using a selector and then unhide one containing a specific selector?


I was marking this a a dupe

CSS Selector: If a Container is empty -> display: none;

Code would be

div { border: 1px solid black; text-align:center; width:400px }
div[id*="accordion_prop_floor_plans"]:empty { display:none }
<div id="accordion_prop_floor_plans_1"></div>
<div id="accordion_prop_floor_plans_2"><img src="https://via.placeholder.com/350x150&text=image" title="image here" /><br/>Plan 2</div>
<div id="accordion_prop_floor_plans_3"></div>

Then I realised that there might be another use case.

Hide divs that do not have a certain element. Or show divs that do.

I tried :has(), based on Is there a CSS parent selector?

but it does not work yet in any browser as of 2018

div { border: 1px solid black; text-align:center; width:400px }
div[id*="accordion_prop_floor_plans"] { display:none }
div[id*="accordion_prop_floor_plans"]:has(> img) { display:block }
<div id="accordion_prop_floor_plans_1">Plan 1</div>
<div id="accordion_prop_floor_plans_2"><img src="https://via.placeholder.com/350x150&text=image" title="image here" /><br/>Plan 2</div>
<div id="accordion_prop_floor_plans_3">Plan 3</div>

I can do it in JS easily:

document.querySelector('div[id*="accordion_prop_floor_plans"]>img').parentNode.style.display="block";
div { border: 1px solid black; text-align:center; width:400px }
div[id*="accordion_prop_floor_plans"] { display:none }
<div id="accordion_prop_floor_plans_1">Plan 1</div>
<div id="accordion_prop_floor_plans_2"><img src="https://via.placeholder.com/350x150&text=image" title="image here" /><br/>Plan 2</div>
<div id="accordion_prop_floor_plans_3">Plan 3</div>
Temani Afif
  • 180,975
  • 14
  • 166
  • 216
mplungjan
  • 134,906
  • 25
  • 152
  • 209
  • yes only the JS works, there is still no CSS solution. Even in 2019 I don't think there will be one. Probably the `:has()` selector will have more support. – Temani Afif Nov 08 '18 at 14:47

1 Answers1

2

As I commented, there is still no CSS solution for such situation since it's closely related to the existence of a parent selector.

By the way, we can still use some specific workarounds in order to show/hide some elements:

Here is an example for this particular case:

div {
  text-align: center;
  width: 400px
}

div[id*="accordion_prop_floor_plans"] {
  position:relative;
  overflow:hidden;
  background:
    linear-gradient(#000,#000) top/100% 1px,
    linear-gradient(#000,#000) bottom/100% 1px;
  background-repeat:no-repeat;
  border-right:1px solid;
  border-left:1px solid;
}
div[id*="accordion_prop_floor_plans"] img {
  margin-top:2px;
  margin-bottom:30px;
}
div[id*="accordion_prop_floor_plans"] > div {
  position:absolute;
  bottom:0;
  left:0;
  right:0;
}
<div id="accordion_prop_floor_plans_1">
  <div>Plan 1</div>
</div>
<div id="accordion_prop_floor_plans_2">
  <img src="https://via.placeholder.com/350x150&text=image" title="image here" />
  <div>Plan 2</div>
</div>
<div id="accordion_prop_floor_plans_3">
  <div>Plan 3</div>
</div>

The idea is to make the text out of the flow and in case there is an image the container will have a height and we will see the text with it. If there is no image, we won't see the text. I also replaced border-top/bottom with gradient to avoid seeing them for the hidden elements.

This remain a hacky solution for this particular case.

Temani Afif
  • 180,975
  • 14
  • 166
  • 216