How exactly does the css in the John Doe no-js webpage manage to make the default home section disappear?

I’m looking at this nice minimal web template: https://john-doe.neocities.org/ (github here: https://github.com/cadars/john-doe/)

This uses the section tag and the :target selector to elegantly create no-js ‘tabs’ that make one particular section visible while hiding all others in the page.

I tried to reproduce this for my site, via the following, simplified css:

section { display: none; }
section:target { display: block; }
section#home { display:block;}

However, this does not have the desired effect, since, while it does indeed achieve the effect that the ‘default’ section will show up in the absence of a #reference in the url, however it does not hide it when another reference is specified. In other words, the section with the ‘home’ id is always displayed, whether it is the target or not.

Whereas in the John Doe page, you will see that if any other target is selected, the #home section is replaced. And if no section is selected (i.e. the URL does not contain a “#” reference), the #home element is indeed visible by default.

I have studied the css style on the John Dow website, but I cannot really see what is the difference between my css and John Doe’s that makes their default #home section behave as expected. Can someone help me figure it out?

Here is a simple testcase:

<html>
  <head>
    <style>
      section { display: none; }
      section:target { display: block; }
      section#first { display: block; }
    </style>
  </head>
  <body>
    <section id="first" > First (default) section </section>
    <section id="second"> Second section          </section>
    <section id="third" > Third section           </section>
  </body>
</html>

What am I missing?

Answer

You can do it like below:

section:target {
  display: block; /* show the targetted one */
}

section:target ~ section, /* all the section after the targetted one hidden*/
section { /* all of them hidden */
  display: none;
}

section:last-of-type {
  display: block; /* last one visible */
}
<section id="second"> Second section </section>
<section id="third"> Third section </section>
<section id="first"> First (default) section </section> <!-- must be the last one -->
<div style="position:absolute;top:10px;right:10px;">
  <a href="#first">first</a>
  <a href="#second">second</a>
  <a href="#third">third</a>
</div>

Or like below:

section:target {
  display: block;
}

section:target ~ section:not(#random),
section {
  display: none;
}

section#first {
  display: block;
}
<section id="second"> Second section </section>
<section id="third"> Third section </section>
<section id="first"> First (default) section </section> <!-- must be not the first one (at least one section before it) -->
<div style="position:absolute;top:10px;right:10px;">
  <a href="#first">first</a>
  <a href="#second">second</a>
  <a href="#third">third</a>
</div>

Leave a Reply

Your email address will not be published. Required fields are marked *