2

I have this code and I would like to have the list be collapsed by default. Here is what it does now.

<!DOCTYPE html>
<head>
   <title>menu mockup</title>
   <style type="text/css">
      .show {display: none; }
      .hide:focus + .show {display: inline; }
      .hide:focus { display: none; }
      .hide:focus ~ #list { display:none; }
      @media print { .hide, .show { display: none; } }
   </style>
</head>
<body>
   <p>Here's a list</p>
      <div>
         <a href="#" class="hide">[hide]</a>
         <a href="#" class="show">[show]</a>
         <ol id="list">
            <li>item 1</li>
            <li>item 2</li>
            <li>item 3</li>
         </ol>
      </div>
   <p>How about that?</p>
</body>
</html>
2
  • It seems to do nothing now? Is it meant to do something/anything? Commented Oct 29, 2012 at 18:30
  • I doesn't seem to work in chrome. I dont know why. I works in firefox and ie Commented Oct 29, 2012 at 18:36

2 Answers 2

2

For this to work in pure CSS requires a change to the HTML (since CSS can only target elements that appear later in the DOM (either as later-siblings, or descendants, or a combination of those two) than the elements upon which they're styled. So, the HTML is now:

<p>Here's a list</p>
<div id="top">
    <ol id="list">
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
    </ol>
    <a href="#top" class="hide">[hide]</a>
    <a href="#list" class="show">[show]</a>
</div>
<p>How about that?</p>​

Note also that the div now has an id in order to allow for the list to be hidden (again, using just CSS and basic HTML).

The CSS is somewhat convoluted, though explained through /* comments in the CSS itself */:

.show,
.hide {
    /* allows for the links to be positioned 'ahead' of the list
       whose appearance they control */
    position: absolute;
    top: 0.1em;
    /* allows for an assigned width, height, etc... */
    display: inline-block;
    width: 5em;
    height: 2em;
    line-height: 2em;
    text-align: center;
}

.hide {
    left: 0;
}

.show {
    /* this is why we have an assigned width */
    left: 5.1em;
}

#list {
    /* hides on page-load */
    display: none;
}

#list:target {
    /* when clicking the 'show' link the #list is targeted
       and is shown */
    display: block;
}

#list:target ~ .show {
    /* reduces the opacity of the 'show' link, when
       the list is already shown */
    opacity: 0.3;
}

#list:target ~ .hide {
    /* when the list is shown, the 'hide' link is visible */
    opacity: 1;
}

#top {
    /* allows the links to be positioned visually ahead of,
       and relative to, the menu */
    position: relative;
    /* slightly greater than the defined height of
       the link elements */
    padding-top: 2.2em;
}

#top .hide,
#top:target  .hide {
    /* hides the 'hide' link when the list is, itself, hidden */
    opacity: 0.3;
}

JS Fiddle demo.

A slightly revised (another element added to wrap the links) version, to allow for more easily positioning them (rather than having to manually work out how wide each link is before setting the left position):

<p>Here's a list</p>
<div id="top">
    <ol id="list">
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
    </ol>
    <!-- could use a div, it doesn't matter -->
    <span id="controls">
        <a href="#top" class="hide">[hide]</a>
        <a href="#list" class="show">[show]</a>
    </span>
</div>
<p>How about that?</p>​

With the CSS:

#controls {
    position: absolute;
    top: 0.1em;
    left: 0;
    height: 2em;
    line-height: 2em;
}

.show,
.hide {
    display: inline-block;
    width: 5em;
    text-align: center;
}

#list {
    display: none;
}

#top {
    position: relative;
    padding-top: 2.2em;
}

#list:target {
    display: block;
}

#list:target ~ #controls .hide {
    opacity: 1;
}

#list:target ~ #controls .show {
    opacity: 0.3;
}

#top #controls .hide {
    opacity: 0.3;
}
#top:target #controls .hide {
    opacity: 0.3;
}

JS Fiddle demo.

Or, instead, using visibility: hidden / visibility: visible;.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks for that. I now have another problem I thought I could just drop this code on the webpage I was working on in WordPress but for some reason I am having trouble. this is the site. the list are in tables. what would make it not work here?
Reproduce the HTML and CSS and add to a Fiddle where I can play with it and see what's going on, and then I'll try and help.
I have been working on some other projects but here it is jsfiddle.net/kkxxr. I have got it with this to hide one of the lists at a time but not all of them. It also doesn't work in chrome. thanks for the help
-1

This html code collapses the list by default

<!DOCTYPE html>
<head>
   <title>menu mockup</title>
   <style type="text/css">
      .show {display: inline; text-decoration: none;}
      .hide {display: none; text-decoration: none;}
      #list {display: none;}
      .show:focus + .hide {display: inline;}
      .hide:focus + #list { display:none;}
      .show:focus ~ #list { display:inline;}
      .show:focus { display:none;}

   </style>
</head>
<body>
   <p>Here's a list</p>
      <div>


         <a href="#" class="show">&#x25BC</a>
         <a href="#" class="hide">&#x25B2</a>
         <ol id="list">
            <li>item 1</li>
            <li>item 2</li>
            <li>item 3</li>
         </ol>

      </div>
  </body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.