javascripthtmlcss

How do I make a div disappear when any other div is targeted?


I've been using CSS tabs to make one page, in which you can navigate through different content using :target. I want to find a way to make it so that one div shows as the home page, without anything being clicked, and it disappears when a div is targeted. I don't want it to be an onclick event, since I want it to be invisible from the other content if you're coming from a link with the targeted ID.

I feel like my best example of what I mean is similar to how carrds work, with the first control being visible when the website loads, but disappearing if there's a different one targeted? I know that for that, it's the same div, but I'm hoping for a simpler solution than whatever carrd has going on. Example

So, this would all be in one HTML document, but I basically want a home page to appear if there's no div targeted, and it goes away if you target a div.

Ideally, in the url, index.html would show the home div, index.html#div01 would make that home div disappear, and instead show a different div with the same content, and index.html#div02 would have completely different content, but I don't know how to get that first part to work. I've been playing around with pseudo-classes and whatever potential solutions I could find online, but nothing's worked quite the way I want it to. Simplifying what I have by removing the unhelpful JavaScript and extra styling, this is what I'm currently sitting with.

Example of what I tried

.tabcontent {
  display: none
}

.tabcontent:target {
  display: block
}

.home {
  display: block
}
<div>
  <a href="#div01"><button>Div 01</button></a>
  <a href="#div02"><button>Div 02</button></a>
</div>
<div class="home tabcontent">
  <p>So this is the home page...</p>
</div>
<div id="div01" class="tabcontent">
  <p>So this is the home page...</p>
</div>
<div id="div02" class="tabcontent">
  <p>And this is something different!</p>
</div>

While I'd like to avoid jQuery if possible, I'll try out anything!


Solution

  • You can do it in pure CSS by leveraging :not() and :has().

      body:not(body:has(.tabcontent:target)) .home {
        display: block;
      }
    
    

    They have good support in modern browsers (with the notable exception of Firefox) but you might need a fallback for old browsers. In this example we check if the browser @supports relational pseudo classes and if not apply some Javascript instead.

    //optional JS fallback for if :has is not supported.
    try {
        document.querySelector(":not(:has(+ *))");
    } catch (error) {
        //not suppoted. do something else
        document.querySelector("a[href='#div01']").click();//maybe manually trigger the click
    }
    .tabcontent {
      display: none
    }
    
    .tabcontent:target {
      display: block
    }
    
    @supports selector(:not(:has(+ *))) {
      body:not(body:has(.tabcontent:target)) .home {
        display: block;
      }
    }
    <div>
      <a href="#div01"><button>Div 01</button></a>
      <a href="#div02"><button>Div 02</button></a>
    </div>
    <div id="div01" class="home tabcontent">
      <p>So this is the home page...</p>
    </div>
    <div id="div02" class="tabcontent">
      <p>And this is something different!</p>
    </div>