Adapting an Unordered List for a Horizontal Menu With Dropdown and Popup

AID: 8715
  • Status: Published

3100 points

  • ByOmniUnlimited
  • TypeTips/Tricks
  • Posted on2011-11-29 at 21:44:09
Unordered lists (HTML ul tags) are very handy to create menus of all types, shapes and sizes.  All it takes is a little knowledge of CSS and the possibilities are endless.

First off, you should know the general format for menus created using the unordered lists or ul tags.  The actual menu links are contained within each of the ul’s list-item (li) tags in a manner similar to this:
 
<ul>
<li><a href=”http://somesite.com/menu-item-1”>Menu Item 1</a></li>
<li><a href=”http://somesite.com/menu-item-2”>Menu Item 2</a></li>
<li><a href=”http://somesite.com/menu-item-3”>Menu Item 3</a></li>
</ul>
                                    
1:
2:
3:
4:
5:

Select allOpen in new window



If you wish to add submenu items to the list, you simply need to contain another ul similar to what you have above within the li tag that you wish to contain the submenu items like so:
 
<ul>
<li><a href=”http://somesite.com/menu-item-1”>Menu Item 1</a>
<ul>
<li><a href=”http://somesite.com/submenu-item-1”>Submenu Item 1</a></li>
<li><a href=”http://somesite.com/submenu-item-2”>Submenu Item 2</a></li>
</ul>
</li>
<li><a href=”http://somesite.com/menu-item-2”>Menu Item 2</a></li>
<li><a href=”http://somesite.com/menu-item-3”>Menu Item 3</a></li>
</ul>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:

Select allOpen in new window



You can continue this process, adding submenu items to submenu items if you wish to create sub-submenu items and beyond:
 
<ul>
<li><a href=”http://somesite.com/menu-item-1”>Menu Item 1</a>
<ul>
<li><a href=”http://somesite.com/submenu-item-1”>Submenu Item 1</a>
<ul>
<li><a href=”http://somesite.com/sub-submenu-item-1”>Sub -submenu Item 1</a></li>
<li><a href=”http://somesite.com/sub-submenu-item-2”>Sub-submenu Item 2</a></li>
</ul>
</li>
<li><a href=”http://somesite.com/submenu-item-2”>Submenu Item 2</a></li>
</ul>
</li>
<li><a href=”http://somesite.com/menu-item-2”>Menu Item 2</a></li>
<li><a href=”http://somesite.com/menu-item-3”>Menu Item 3</a></li>
</ul>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen in new window



Now, if you do this, your end result will look similar to this:
 
screenshot.png
  • 58 KB
  • Unordered List Display
Unordered List Display


Not very impressive, is it?  Not to worry, here is where the magic of CSS comes into play.  For my example, I will use the last ul structure I gave you since it is the most complicated, and will demonstrate the power of some well placed CSS.

In this article, I will be setting up a horizontal menu, with a vertical drop-down submenu and a popup to the right sub-submenu.

First off, let’s add some well placed classes and id’s to the mix (you can do this any way you feel is best.  Use mine simply as an example):
 
<ul id="menu">
<li class="main"><a href="http://somesite.com/menu-item-1">Menu Item 1</a>
<ul>
<li class="sub1"><a href="http://somesite.com/submenu-item-1">Submenu Item 1</a>
<ul>
<li class="sub2"><a href="http://somesite.com/sub-submenu-item-1">Sub -submenu Item 1</a></li>
<li class="sub2"><a href="http://somesite.com/sub-submenu-item-2">Sub-submenu Item 2</a></li>
</ul>
</li>
<li class="sub1"><a href="http://somesite.com/submenu-item-2">Submenu Item 2</a></li>
</ul>
</li>
<li class="main"><a href="http://somesite.com/menu-item-2">Menu Item 2</a></li>
<li class="main"><a href="http://somesite.com/menu-item-3">Menu Item 3</a></li>
</ul>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen in new window



There are a variety of different ways you can achieve the effect of the horizontal menu.  I will be sharing with you the method that works best for me.

Now that we have the HTML laid out properly with some strategically placed classes and id’s, let’s go ahead and start putting together the horizontal menu.

My method involves the use of floats, so you need to be sure that any floats that you have set on your page before this menu have been properly cleared otherwise you will not get the results as I will be describing them to you.

There are some browser set margins and padding that could interfere with your menu setup, so it is important that you do some preliminary CSS at the beginning of your CSS file:
 
*
{
     margin: 0;
     padding: 0;
}
                                    
1:
2:
3:
4:
5:

Select allOpen in new window



The asterisk is a universal CSS selector and will reset all elements margins and paddings back to 0.

Now, let’s start by getting rid of the default list bullets and setting a float to the li’s in the list like so:
 
ul#menu
{
     list-style: none;
}

ul#menu li
{
      float: left;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:

Select allOpen in new window



Doing that to our example menu gives us this:
 
screenshot2.png
  • 56 KB
  • Unordered List Modified For Menu
Unordered List Modified For Menu


Again, not too impressive, but you can see that the bullets are gone and that the menu items, for the most part, are together on the same line as the previous same level item.  The only exceptions are the menu items that have submenu items, as these submenu items cause gaps in between the main menu items.

I would recommend at this point that you add a break or a div after the menu whose style is set to clear the floats so that the rest of your page doesn’t get messed up.

I use the following class:
 
.clearfloat { /* this class should be placed on a div or break element and should be the final element before the close of a container that should fully contain a float */
    clear:both;
    height:0;
    font-size: 1px;
    line-height: 0px;
}
                                    
1:
2:
3:
4:
5:
6:

Select allOpen in new window



and add it to a break at the end of the menu like so:
 
<ul id="menu">
<li class="main"><a href="http://somesite.com/menu-item-1">Menu Item 1</a>
<ul>
<li class="sub1"><a href="http://somesite.com/submenu-item-1">Submenu Item 1</a>
<ul>
<li class="sub2"><a href="http://somesite.com/sub-submenu-item-1">Sub -submenu Item 1</a></li>
<li class="sub2"><a href="http://somesite.com/sub-submenu-item-2">Sub-submenu Item 2</a></li>
</ul>
</li>
<li class="sub1"><a href="http://somesite.com/submenu-item-2">Submenu Item 2</a></li>
</ul>
</li>
<li class="main"><a href="http://somesite.com/menu-item-2">Menu Item 2</a></li>
<li class="main"><a href="http://somesite.com/menu-item-3">Menu Item 3</a></li>
</ul><br class="clearfloat" />
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen in new window



Since our goal was to create a vertical dropdown under the main menu items, let’s set the float on the submenu items to none as follows:
 
ul#menu li ul li
{
      float: none;
}
                                    
1:
2:
3:
4:

Select allOpen in new window



This gives us the following:
 
screenshot3.png
  • 57 KB
  • Menu Modified For Vertical Dropdown
Menu Modified For Vertical Dropdown


As you can see, the submenu items are now going down vertically as was our original intention, but it appears that the sub-submenu items are also in the same column.  Let’s not worry about this for now.  We will fix that later.

Right now, let’s start making these ugly looking links look more like menu buttons.  Add some CSS for the main menu buttons by setting the styles for the main menu anchor tags:
 
ul#menu li.main a
{
   width: 110px;
   height: 20px;
   padding: 10px 20px;
   display: block;
   font-weight: bold;
   background-color: #000;
   color: #FFF;
   text-decoration: none;
   text-align: center;
}

ul#menu li.main a:hover
{
   background-color: #666;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:

Select allOpen in new window



Adding the above CSS makes the unordered list look like the following:
 
screenshot4.png
  • 58 KB
  • Stylized Menu Buttons
Stylized Menu Buttons


But, oh wow, what happened?  Didn’t we add CSS just to the li.main a elements?  Why then are all the submenu items styled as well?

The submenus anchor tags got styled because they are considered to also be li.main a tags (in other words, anchor tags within an li.main tag).  It is important to realize that the selector, li.main a, is telling your browser to style all anchor tags within an li.main element.  It doesn't matter if that anchor is found encased several elements deep within li.main.

In order to correct this, we need to style the submenus.  Remember as you style the submenus, that any style you do not override in your submenu styles will be carried over from the li.main a styling.

Let’s set up the submenus a little different, and let’s increase the width so that the menu labels don’t have to wrap, and set the text alignment to the left:
 
ul#menu li.main ul li.sub1 a
{
   width: 150px;
   padding: 5px 20px;
   background-color: #CCC;
   color: #000;
   text-align: left;
}

ul#menu li.main ul li.sub1 a:hover
{
   background-color: #EEE;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:

Select allOpen in new window



This gives us something like this:
 
screenshot5.png
  • 57 KB
  • Stylized Submenus
Stylized Submenus


“Now it’s starting to look like something”, you say, “But we still have the gap between the first and second main menu items and the sub-submenu items are still in line with the submenu items?”

Not to worry.  This is where a little absolute and relative positioning come into play.

First, let’s make the li’s relatively positioned so that they can act as containers for the absolutely positioned ul’s we will need by adding that style to the already existing ul#menu li like so:
 
ul#menu li
{
	float: left;
	position: relative;
}
                                    
1:
2:
3:
4:
5:

Select allOpen in new window



Now we can set the positions of the ul’s for each of the sub and sub-submenus by using absolute positioning:
 
ul#menu li.main ul
{
	position: absolute;
	top: 40px;
}

ul#menu li.main ul li.sub1 ul
{
	position: absolute;
	top: 5px;
	left: 190px;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window



Doing so gives us the following:
 
screenshot6.png
  • 56 KB
  • Submenus Correctly Positioned
Submenus Correctly Positioned


“Hey, that’s pretty good!”, you say, “but didn’t you say the submenus were supposed to be drop-down and the sub-submenus pop-up?”

Thanks for noticing.  That is the last step in our process.  In order to achieve this effect, we need to take the styles we just added and modify them slightly by simply adding display: none to the indicated selectors, then use display: block on the hover pseudo-class of the affected li and ul tags like so:
 
ul#menu li.main ul
{
	position: absolute;
	top: 40px;
	display: none;
}

ul#menu li.main:hover ul, ul#menu li.main ul:hover
{
	display: block;
}

ul#menu li.main ul li.sub1 ul
{
	position: absolute;
	top: 5px;
	left: 190px;
	display: none;
}

ul#menu li.main ul li.sub1:hover ul, ul#menu li.main ul li.sub1 ul:hover
{
	display: block;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:

Select allOpen in new window



Your menu now should look similar to the following:
 
screenshot7.png
  • 54 KB
  • Menu With Dropdown and Popup
Menu With Dropdown and Popup

 
screenshot8.png
  • 56 KB
  • Hover Over Main Menu Item
Hover Over Main Menu Item

 
screenshot9.png
  • 57 KB
  • Hover Over Submenu Item
Hover Over Submenu Item


That’s all it takes to make a very basic, but fully functional horizontal menu with dropdowns and popups.  You can add as many submenus and sub-submenus as you like and there will be little if no further need to change the CSS.  Deeper level submenus (e.g. sub-sub-submenus, etc.) can be set up by simply following the logic of the CSS flow.  If you desire something different, you can use your own ingenuity by adding more CSS, background images, and maybe even some javascript.  Really there is no limit to what you can achieve with a little knowledge and a little creativity.

Should you have any problems in setting up your menus, I do invite you to make use of the experts here at EE.  We can help you set up just about any menu you can think of.

The complete CSS for this menu is as follows:
 
*
{
	margin: 0;
	padding: 0;
}

ul
{
     list-style: none;
}

ul#menu li
{
	float: left;
	position: relative;
}

ul#menu li ul li
{
      float: none;
}

ul#menu li.main a
{
   width: 110px;
   height: 20px;
   padding: 10px 20px;
   display: block;
   font-weight: bold;
   background-color: #000;
   color: #FFF;
   text-decoration: none;
   text-align: center;
}

ul#menu li.main a:hover
{
   background-color: #666;
}
 
ul#menu li.main ul
{
	position: absolute;
	top: 40px;
	display: none;
}

ul#menu li.main:hover ul, ul#menu li.main ul:hover
{
	display: block;
}

ul#menu li.main ul li.sub1 ul
{
	position: absolute;
	top: 5px;
	left: 190px;
	display: none;
}

ul#menu li.main ul li.sub1:hover ul, ul#menu li.main ul li.sub1 ul:hover
{
	display: block;
}

ul#menu li.main ul li.sub1 a
{
   width: 150px;
   padding: 5px 20px;
   background-color: #CCC;
   color: #000;
   text-align: left;
}

ul#menu li.main ul li.sub1 a:hover
{
   background-color: #EEE;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:

Select allOpen in new window



Best of luck to you on all your future projects!
    Asked On
    2011-11-29 at 21:44:09ID8715
    Tags

    CSS

    ,

    menu

    ,

    unordered list

    ,

    popups

    ,

    dropdowns

    Topic

    Cascading Style Sheets (CSS)

    Views
    2335

    Comments

    Add your Comment

    Please Sign up or Log in to comment on this article.

    Join Experts Exchange Today

    Gain Access to all our Tech Resources

    Get personalized answers

    Ask unlimited questions

    Access Proven Solutions

    Search 3.2 million solutions

    Read In-Depth How-To Guides

    1000+ articles, demos, & tips

    Watch Step by Step Tutorials

    Learn direct from top tech pros

    And Much More!

    Your complete tech resource

    See Plans and Pricing

    30-day free trial. Register in 60 seconds.

    Loading Advertisement...

    Top CSS Experts

    1. COBOLdinosaur

      213,892

      Guru

      0 points yesterday

      Profile
      Rank: Genius
    2. LZ1

      169,513

      Guru

      0 points yesterday

      Profile
      Rank: Genius
    3. DaveBaldwin

      108,635

      Master

      2,000 points yesterday

      Profile
      Rank: Genius
    4. ChrisStanyon

      101,266

      Master

      0 points yesterday

      Profile
      Rank: Sage
    5. tommyBoy

      65,616

      Master

      0 points yesterday

      Profile
      Rank: Genius
    6. kozaiwaniec

      57,116

      Master

      2,000 points yesterday

      Profile
      Rank: Guru
    7. nap0leon

      53,757

      Master

      0 points yesterday

      Profile
      Rank: Sage
    8. xmediaman

      50,100

      Master

      0 points yesterday

      Profile
      Rank: Guru
    9. jason1178

      49,680

      0 points yesterday

      Profile
      Rank: Genius
    10. SSupreme

      43,018

      0 points yesterday

      Profile
      Rank: Wizard
    11. Kravimir

      42,150

      0 points yesterday

      Profile
      Rank: Genius
    12. s8web

      40,064

      0 points yesterday

      Profile
      Rank: Sage
    13. therealteune

      35,300

      0 points yesterday

      Profile
      Rank: Wizard
    14. webmatrixpune

      30,818

      0 points yesterday

      Profile
      Rank: Guru
    15. HagayMandel

      27,880

      0 points yesterday

      Profile
      Rank: Guru
    16. zappafan2k2

      23,368

      0 points yesterday

      Profile
      Rank: Guru
    17. leakim971

      22,966

      0 points yesterday

      Profile
      Rank: Genius
    18. HainKurt

      20,000

      0 points yesterday

      Profile
      Rank: Genius
    19. jagadishdulal

      19,668

      0 points yesterday

      Profile
      Rank: Guru
    20. Proculopsis

      19,350

      0 points yesterday

      Profile
      Rank: Sage
    21. mplungjan

      19,232

      0 points yesterday

      Profile
      Rank: Savant
    22. basicinstinct

      19,026

      0 points yesterday

      Profile
      Rank: Genius
    23. anuradhay

      19,006

      0 points yesterday

      Profile
      Rank: Guru
    24. jtwcs

      18,808

      0 points yesterday

      Profile
      Rank: Master
    25. gurvinder372

      18,057

      0 points yesterday

      Profile
      Rank: Genius

    Hall Of Fame