Приглашаем посетить
Чулков (chulkov.lit-info.ru)

Creating Drop-Down Menus

Previous Page
Table of Contents
Next Page

Creating Drop-Down Menus

Now we need to take our horizontal list a step further and add drop-down choices. CSS-based drop-down menus aren't going to work in Internet Explorer for Mac. I will, however, show you a way you can use CSS so that your menu degrades nicely in this browser and still offers the user an acceptable navigation experience.

In the following exercise, we'll assume that the horizontal menu items each have a related page, and we'll code their responses accordingly. All you need to do is add URLs in place of the # symbols in each link's HRef.

Marking Up Drop-Down Menus

To mark up a drop-down menu, we need to nest a complete list within a list item of the horizontal menu. This nested list becomes the contents of that list item's drop-down menu. Figure 7.21 shows the finished menu so you can see what you are shooting for.

Figure 7.21. Here's your completed drop-down menu.

Creating Drop-Down Menus


Here's the complete markup for a menu with four choices, each with a drop-down

<body>
<div id="listcontainer" class="clearfix">
<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></li>
    </ul>
  </li>
  <li><a href="#">Members</a>
    <ul> <!-- drop-down menu items-->
        <li><a href="#">Benefits</a></li>
        <li><a href="#">Programs</a></li>
        <li><a href="#">Renewals</a></li>
        <li><a href="#">Questions?</a></li>
    </ul>
 </li>
  <li><a href="#">Dealers</a>
    <ul> <!-- drop down menu items-->
        <li><a href="#">Join us</a></li>
        <li><a href="#">Programs</a></li>
        <li><a href="#">National Network Map</a></li>
        <li><a href="#">Support</a></li>
    </ul>
  </li>
  <li><a href="#">Distributors</a>
    <ul> <!-- drop down menu items-->
        <li><a href="#">Products</a></li>
        <li><a href="#">Dealer Finder</a></li>
        <li><a href="#">Commissions</a></li>
        <li><a href="#">Customers</a></li>
    </ul>
  </li>
</ul>
</div>
</body>

Here are a couple of notes about the markup:

  1. None of the ul or li elements have classes or IDsin fact, the only thing that differentiates this list from a regular nested list is the containing div, with its ID listcontainer, which causes the appropriate CSS rules to target the list.

  2. This markup is the same as the previous exercise's horizontal navigation bar, but with a sublist nested inside each list item. It is vital to nest the list correctlyyou must put the entire nested list, from ul to /ul, inside of a list item, right before the list item's closing /li, as this simple example, with the nested list highlighted, illustrates

    <ul>
    <li><a href="#">This is a top level item 1, without a drop-down</a></li>
    <li><a href="#">This is a top level item 2, with a drop-down</a>
    <ul>
    <li><a href="#">This is item 1 of the drop-down</a></li>
    <li><a href="#">This is item 2 of the drop-down</a>
    </ul>
    </li> <!--note this is the close of top-level list item 2-->
    <li><a href="#">This is a top level item 3, without a drop-down</a></li>
    </ul>
    

  3. href values are simply designated as #a placeholderin this markup. This placeholder does nothing; you need to replace each # with an appropriate URL, either relative or absolute, to point to the relevant page.

Let's start simply. Instead of working immediately with the final markup earlier in this section, start with the horizontal navigation markup, which has a sublist added to only the first li. You will add the other nested lists after you have one menu working correctly. Here's the markup

<body>
<div id="listcontainer" class="clearfix">
 <ul>
  <li><a href="#">Customers</a>
     <ul> <!-- drop down-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></li>
    </ul>
 </li>
  <li><a href="#">Members</a></li>
  <li><a href="#">Dealers</a></li>
  <li><a href="#">Distributors</a></li>
 </ul>
</div>
</body>

Now take a look at Figure 7.22.

Figure 7.22. The submenu is not stacked like a drop-down yet, but it is inheriting the styles from the parent list, as shown when you point at a link.

Creating Drop-Down Menus


We need some styles specifically for the drop-down menu to get it to stack under its parent element.

Instead of adding a class or ID to the submenu so we can target it, just write a selector that only affects a list that is within a list. For example, the selector ul li ul {…some CSS here…} only targets a ul element that is contained within the li element of a parent listjust what we want. As you can see in the following code, just three simple CSS declarations get you well on the way to the desired result

div#listmenu ul li ul {        <-- a
   margin:0;        <-- b
   width:10em;        <-- c
   }
div#listmenu ul li ul li {
   width:100%;        <-- d
   }        <-- e

(a)The drop-down starts here

(b)Prevents the temp margin on the ul from inheriting here

(c)Sets the width of the menu; in combo with the li's 100% width, makes the menu stack

(d)Makes the list items fill the list container (ul)

(e)The drop-down menu ends here

Now take a look at Figure 7.23.

Figure 7.23. Although this menu needs better styling and doesn't yet open and close automatically, it is starting to look like a drop-down menu.

Creating Drop-Down Menus


If we set the width of the ul of the nested list, and then force the li elements within to be 100 percent of that width, they stack nicely. Without the 100 percent width on the li, the short words, "FAQs" and "Sign Up," would be on the same line, and each li element would be a different length.

The next step is to get drop-downs correctly positioned with respect to the menu. The way to do this is to set the child element's position property to absolute and the parent's to relative. At the same time, we'll want to correctly style the drop-down's borders, so we can see that the drop-down is, in fact, accurately aligned to the menu. Here's the code

div#listmenu li {
   float:left;        <-- a
   position:relative;        <-- b
   list-style-type:none;
   background-color:#FFA;
   border-right:1px solid #069;
   }
div#listmenu ul li ul {
   margin:0;
   position:absolute;        <-- c
   width:10em;
   }
div#listmenu ul li ul li {
   width:100%;        <-- d
   border-left:1px solid #069;        <-- e
   border-bottom:1px solid #069;
   border-right:1px solid #069;
   }
div#listmenu ul li ul li:first-child {
   border-top:1px solid #069;        <-- f
   }

(a)Causes the list to align horizontally

(b)Positioning context for the absolutely positioned drop-down

(c)Positions the drop-down ul in relation to its relatively positioned li parent

(d)Makes the list items fill the list container (ul)

(e)Three sides of each drop-down item

(f)The top edge of the drop-down

Now take a look at Figure 7.24.

Figure 7.24. With the contextual positioning set, and the borders styled, you can see that the alignment of the drop-down to the menu is almost perfect.

Creating Drop-Down Menus


The drop-down is 1 pixel off because it aligns with the list item, not the list item's border, but because its positioning context is now its parent element (its position is set to absolute, the parent to relative), it's just a matter of defining a left offset to nudge it into the correct location. Here's what to do

div#listmenu ul li ul {
   margin:0;
   position:absolute;
   width:10em;
   left:-1px;        <-- a
   }

(a)Aligns the drop-down exactly under the menu

Now look at Figure 7.25.

Figure 7.25. Now the drop-down is correctly positioned under the menu.

Creating Drop-Down Menus


With the exception of some styling problems in Internet Explorer (a missing top line, and the inherited left ul border from an earlier hack) that we will fix later, the drop-down is now nicely styled, and we're ready to make it visible only when the pointer is over the appropriate choice of the menu.

In the horizontal menu, the element that changes is the one that is being hovered over, but in the case of the drop-down menu, that's not true. The drop-down should display when its parent menu (the choice on the horizontal menu) is hovered over. A brilliantly simple selector makes that happen.

First, hide the drop-down when it's not being hovered over, like this

body div#listcontainer ul li ul {display:none;}

Display is inherited, so all the list items within the ul disappear too. With the drop-down hidden, next make it appear when the drop-down's menu choice is hovered, like this

div#listcontainer ul li:hover ul {display:block;}

This selector states that the drop-down ul should display when its parent li is hovered over. However, we also want the menu to remain visible when we move off the parent menu choice and onto the drop-down itself. To do so, group a second selector with the display:block declaration like this

div#listcontainer ul li:hover ul, div#listcontainer ul li ul:hover {display:block;}

Now the menu is displayed is when you hover over either the menu or the drop-down, and your menu springs to life (Figure 7.26).

Figure 7.26. When the menu is hovered over, the drop-down displays. The menu remains highlighted while the user moves on to the drop-down.

Creating Drop-Down Menus


Now perform the fixes for Internet Explorer, like this

* html  div#listmenu ul li ul {        <-- a
   border-top:1px solid #069;
   border-left:0px;        <-- b
   }

(a)Add a top line to drop-downs in IE browsers

(b)Stops the drop-down from inheriting the ul border

Now Internet Explorer displays the drop-down as other browsers do.

One thing you'll notice is that the drop-down text doesn't highlight when you are on a drop-down list item, only when you are on the text itself. Let's deal with that next. To deal with this, you might think you would need to set the drop-down links to block, but as it turns out, you have to set the parent (the menu) links to block for all browsers at this point. Here's how it works

div#listmenu a {
   display:block;        <-- a
   padding:0 6px;        <-- b
   text-decoration:none;        <-- c
   color:#069;        <-- d
   }

(a)List items in drop down highlight and wrapped lines indent correctly

(b)Creates space each side of menu item's text

(c)Removes the link underlining

(d)sets the type color

Now you'll see Figure 7.27.

Figure 7.27. Now the links highlight when the pointer moves over the list items.

Creating Drop-Down Menus


So now we can remove the Internet Explorer hack from the horizontal menu exercise that set the menu links to block; it turns out we need that setting for all browsers. You'll delete this line of code

Creating Drop-Down Menus

An interesting bonus is that, if a choice in the drop-down wraps to a second line, it also indents according to the padding instead of touching the edge of the list item.


* html a {display:block;}

We now have drop-down menus built from basic list markup and without a line of JavaScript in sight.

    Previous Page
    Table of Contents
    Next Page