Ïðèãëàøàåì ïîñåòèòü
ßçûêîâ (yazykov.lit-info.ru)

Making Multiple Level Drop-Downs

Previous Page
Table of Contents
Next Page

Making Multiple Level Drop-Downs

So far we have a menu with a drop-down that allows the user to drill down to the second level of the site. With a little more effort, we can enable users to navigate directly to much lower levels of the site, like what is going on in Figure 7.28.

Figure 7.28. Pop-out menus that become visible when choices are made in the drop-down enable users to have direct access to the lower levels of a site.

Making Multiple Level Drop-Downs


So now (in Figure 7.28) you have the horizontal menu, the drop-down, and pop-outs that offer direct access to third and fourth levels of pages. There are two quite simple steps we need to take to add these pop-outs. First, we must modify the markup to add the pop-out items within the nested lists of the drop-downs. This requires a degree of care, but if you are generating the lists according to a database structure, it's a programmer's dream; every time there is another level, we just generate another list within a list item. This format is ideally suited to basic recursive-loop programming techniques.

First, add just one pop-out by extending your markup like this

<div id="listmenu">
 <ul>
  <li><a href="#">Customers</a>
      <ul><!-- drop down menu items -->
        <li><a href="#">Our Services</a></li>
        <li><a href="#">FAQs</a></li>
        <li><a href="#">Sign Up</a></li>
        <li><a href="#">Support</a>
         <ul><!pop-out menu items -->
            <li><a href="#">Gold program</a></li>
            <li><a href="#">Silver program</a></li>
            <li><a href="#">Bronze program</a></li>
            <li><a href="#">By Region</a></li>
         </ul>
         </li>
         <li><a href="#">What's New</a></li>
        </ul>
   </li>
   <li><a href="#">Members</a>...
  (...unchanged to end...)

Then add two lines to your CSS

body div#listmenu ul li ul li ul  {        <-- a
   visibility:hidden;        <-- b
   left:10em;
   }
div#listmenu ul li ul li:hover ul {visibility:visible;}        <-- c

(a)Pop-out starts here

(b)Same effect as display:none

(c)Same effect as display:block

As you can see from the long selectors, we are now selecting lists within lists within lists; adding body to the first list ensures that it has a higher specificity than the selector for the level above. Note that we push the pop-out over by the width of the drop-down.

The additional markup and CSS gives you Figure 7.29.

Figure 7.29. The pop-out is functional, but it takes on the same positioning offset as the drop-down and sits below the choice instead of next to it.

Making Multiple Level Drop-Downs


Although we got the left offset right, clearly the pop-out is much too low; it should align with the top of the drop-down choice, but it's almost aligned with the next choice in the drop-down. At the moment, it's inheriting the vertical offset that positions the drop-downs under the horizontal menu; that's why it is too low. It just takes one line of CSS to correct this

body div#listmenu ul li ul li ul  {        <-- a
   visibility:hidden;        <-- b
   top:-1px;
   left:10em;
   }
div#listmenu ul li ul li:hover ul {visibility:visible;}        <-- c

(a)Pop-out starts here

(b)Same effect as display:none

(c)Same effect as display:block

Now it is perfectly positioned (Figure 7.30). (Setting top to 0px instead of the 1px offset aligns the menu with the top of the list item rather than the top of its border.)

Figure 7.30. With the top property set, the pop-out aligns correctly with the drop-down.

Making Multiple Level Drop-Downs


By nesting another list and adding two more lines of CSS

div#listmenu ul li ul li:hover ul li ul {visibility:hidden;}
div#listmenu ul li ul li ul li:hover ul {visibility:visible;}

you can support another level of menus.

Making Multiple Level Drop-Downs

The code for the finished style sheet is over two hundred lines with the CSS and the markup. You can find it on the Stylin' Web site (www.bbd.com/stylin).


Rollovers with Graphical Backgrounds

In the drop-down menu example, each menu item's background changed color when it was rolled over. We achieve this by having the element's color value change on :hover. However, sometimes, rather than wanting to change the background color, we want to have a graphic background change.

In the past, this meant you had to make different graphics for each state of the button and then use JavaScript. If you have done this before, you know how much work is involved for a relatively simple effect; if you haven't, you'll be pleased to know that you don't have to do this any more, because there is a much easier way to achieve the same effect using CSS.

Typically the markup for a graphical button is something like this

<div class="button">
<a class="roll" href="#">Graphics</a>
</div>

So that the whole of the area of the div (or whatever the container might be) responds to the rollover, you need to force the anchor link to fill it, so you need some CSS like this

div.button {
   width:120px;
   height:24px;
   top:0px;
   left: 0px;
   border: 1px #000 solid;
   }
a.roll {width:120px;
   height:24px;
   display:block;
   padding-top:2px;
   font: bold 10pt;
   text-align:center;
   border:1px solid red;        <-- a
       }

(a)Temp to check link fills div

Note that here we change the link to a block level element so that it responds to the specified dimensions instead of shrink-wrapping the text, and we temporarily add a red border so that we can see that it actually does (Figure 7.32).

Figure 7.32. When the link's display property is set to block (from the default inline), it can be sized to fill the div. Now the whole div is hot, not just the text.

Making Multiple Level Drop-Downs


With the div filled by the link element, the link switches to the :hover state when the mouse enters the div.

At this point, we need to add the CSS LoVeHAte relationship for the links

div.button a.roll:link {color: black; text-decoration:none;}
div.button a.roll:visited {color: black; text-decoration:none;}
div.button a.roll:hover {color:#069; text-decoration:underline;}
div.button a.roll:active {color:#CCC;}

This removes the default underlining; instead, the link becomes underlined when the mouse is in the a element, which now fills the div.

The next step is to create a graphic with all four of the required states of the button on it. Minimally, this includes the :link (normal, unrolled) state and a :hover state, but you can have up to four by adding the :active (mouse button down) state and the :visited state. Figure 7.33 shows a graphic with all four states.

Figure 7.33. Here's a four-state button graphic.

Making Multiple Level Drop-Downs


This graphic is 120 by 100 pixels and each button is 120 by 24 pixels. Now put this graphic into the background of our a element, like this


a.roll  { a.roll  {width:120px; height:20px; display:block; padding-top:2px; font: bold
Making Multiple Level Drop-Downs 10pt; text-align:center;
background:  url("images_pres/four_state_roll_bg.gif") 0px 0px no-repeat #000;}

You now have what is shown in Figure 7.34.

Figure 7.34. The background image is masked by the div so only one button area shows.

Making Multiple Level Drop-Downs


The background property is actually shorthand for all the other background properties. In one line, we specify the background's source image, its left and top location with respect to the container, its tiling repeat, and a background color of black. (The background-color is always behind the background-image, so in this case, where the graphic fills the background, the background color doesn't show).

Now we are ready for the last stepmaking the graphic change. The container is acting like a window through which we can see part of the larger graphic. All we have to do is move the graphic up and down behind the container and the background will appear to change. Here's the code

div.button a.roll:link {background-position: 0px 0px; color: black; text-decoration:none;}
div.button a.roll:visited {background-position: 0px -25px; color: green;}
div.button a.roll:hover {background-position: 0px -50px; color:#069;}
div.button a.roll:active {background-position: 0px -75px; color:white;}

Using the background-position property, we are causing the graphic to be repositioned with each change of state of the a link. One graphic, no JavaScript, no preloading of imagesthat's the CSS way to create graphical rollovers.

    Previous Page
    Table of Contents
    Next Page