Community Pick: Many members of our community have endorsed this article.
Editor's Choice: This article has been selected by our editors as an exceptional contribution.

Creating Simple CSS Menus without Javascript

Pieter MaraisSenior Developer
CERTIFIED EXPERT
Published:
Updated:
In this tutorial I will explain to you how to create CSS Menus using unordered lists and style sheets.

The reason behind using unordered lists is simple: It is easy to use and it looks neat in the HTML ^_^

1. First things first


First things first. While I was developing this menu, it sometimes worked, and other times not. This was because I used the wrong <!DOCTYPE /> tag at the top of my HTML pages.

So for this menu to function correctly, you will need to put the following  <!DOCTYPE /> tag at the top of your HTML page:
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Open in new window


Now, lets get started.

2. The HTML - <ul>, <li> and <dt>


I am using a clean HTML template for this example. You can copy it into a text editor, if you would like to follow along. I will be using this template throughout this tutorial, so whenever you read the words "HTML template", know that I am referencing this specific html template:
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
                      <html> 
                      <head> 
                      <title>CSS Menu</title> 
                      <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> 
                      </head> 
                      <body> 
                      </body> 
                      </html>

Open in new window


Now, the menu basically consists of nested <ul> , <li> and <dt> tags, which are relatively easy to understand and work with. By nested, I mean adding another <ul> tag inside a <li> tag.The <dt> tags are only there to format the text inside a <li> tag. Here is an example that you can place inside the body section of the HTML template. It is very basic and contains only one nested <ul> tag. Also, give the first <ul> tag a class name of "mainmenu":
<ul class="mainmenu">
                      <li>
                         <dt>Websites</dt> 
                         <ul> 
                            <li><dt>Divetime</dt></li> 
                            <li><dt>DropZone</dt></li> 
                            <li><dt>Rockclimbing</dt></li> 
                         </ul> 
                      </li> 
                      <li>
                         <dt>Electronics</dt>
                      </li> 
                      <li>
                         <dt>Home</dt>
                      </li> 
                      </ul> 

Open in new window


The CSS - A Tired Walk Through


It looks rather nice if you preview it in a browser, doesn't it? ^_^
Lets make it look even nicer. Add a style sheet section just before the closing <head> tag (Note: External style sheets can also be used, but for the sake of simplicity, I will be using this method) We will also create a CSS class for our menu. We will call it "mainmenu" :
 
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
                        <style>
                          .mainmenu {
                          
                          }
                        </style>
                      </head>

Open in new window


When you think of a menu, you think of a list of items, listed one below the other, inside visually attractive, rectangular boxes, right? To give you an idea of how these "boxes" look like at the moment, add a new style to your style sheet that will draw a border around the <li> elements. Remember though, we only want to draw borders around the <li> that are inside the "mainmenu" <ul> element, not all of the <li> elements of the html document, so we will need to prefix the style for the <li> element with the class name of the <ul> element:
 
    .mainmenu li {
                              border: 1px solid black;
                          }

Open in new window


Preview it in a browser. It looks a bit ugly, I know, but know you will have a basic idea of what the layout of the <li> elements are at the moment. To remove the bullets in front of the <li> elements, we need to set the "list-style-type" ,of all the <ul> elements in the menu, to "none". Add the style property "list-style-type:none;" to the "mainmenu" class. This will only remove the bullets from the main <ul> element. To remove the rest, add another style to the style sheet for the <ul> elements inside the "mainmenu" <ul> element.It might also be a good idea to set both the "mainmenu" <ul> element and the other <ul> elements' margins to 0px. We will also add "width:250px" and "height:30px" properties to the <li> elements, to reign them in a bit. When you are done, the three styles should look like the following:
 
    .mainmenu {
                              list-style-type:none; 
                              margin:0px;
                          }
                          
                          .mainmenu li {
                              border:1px solid black;
                              width:150px;
                              height:25px
                          }
                          
                          .mainmenu li ul {
                              list-style-type:none; 
                              margin:0px;
                          }

Open in new window



See? It is starting to take shape now. Just to make it look a little better, add a background color to the <li> elements by using the styles. I also changed the border color, just to make it fit with the theme ^_^
 
    .mainmenu li {
                              border:1px solid #AEB6F4;
                              background:#D2D6F9;
                              width:150px;
                              height:25px;
                          }

Open in new window


Preview the changes in a browser. What?! Did you see that? Its looking all weird. That one menu is laying underneath the other two <li> elements. We can fix that by setting the positioning of the <ul> elements , inside the "mainmenu", to "relative".And while we are at it, lets move the menu a little bit up and more to the right.
 
    .mainmenu li ul {
                              list-style-type:none;
                              margin:0px;
                              position:relative;
                              top: -15px;
                              left: 50px;
                          }

Open in new window


There we go. It looks a lot like a menu, but it still is not behaving like one. Something should happen if you hover the mouse over one of the items, like, for instance, lighting it up a bit or making it darker, just to stand out. Lets add a hover style for the <li> elements inside the "mainmenu" <ul> element to the style sheet:
    .mainmenu li:hover {
                              background:#88A2FB;
                          }

Open in new window

 

4. Showing and Hiding the Menus

It is missing one more thing, for it to behave like a menu. The menu needs to disappear and reappear as you hover the mouse over its parent <li> element. To make it disappear is simple. Set the "display" property of only the <ul> elements inside the "mainmenu" <ul> element to "none". We don't want the "mainmenu" to disappear as well:
 
    .mainmenu li ul {
                              list-style-type:none;
                              margin:0px;
                              position:relative;
                              top: -15px;
                              left: 75px;
                              display:none;
                          }

Open in new window


To make it reappear when the mouse hovers over its parent <li> element, we will need to create a style which will make it visible again:
 
    .mainmenu li:hover ul {
                              display:block;
                          }

Open in new window


Looks nice. It behaves just like any other menu. But what if I want to make the items in the menu, link to another page on my website? No problem at all. I suggest using anchor tags around the visible contents of a <li> element (That is EXCLUDING a nested <ul> element if there is one) and add another style for the anchor tags inside the "mainmenu" <ul> element. This is also the point where we will add some padding to the <dt> elements by adding another style in the style sheet:

<li> element with anchor tag:
 
<li><a target="_blank" href="http://www.divetime.com/"><dt>Divetime</dt></a></li>

Open in new window


Style of the anchor tag and <dt> tag with some formatting applied:
    .mainmenu a {
                              display:block;
                              width:125px;
                              height:25px;
                              text-decoration:none;
                          }
                      
                          .mainmenu dt {
                              margin-top:3px;
                              padding-left:7px;
                          }

Open in new window

 

5. Multi Level Menus

And finally, the last thing. This menu only supports the correct display of one level of menus. Adding support for more is very easy. All you need to do is create an extra 2 styles for the hiding and displaying of the menus for each level you want to add. I know it sounds difficult, but let me demonstrate for you. Here are the hide and show styles of the menu for one level (The current one):
 
    .mainmenu li ul {
                              list-style-type:none;
                              margin:0px;
                              position:relative;
                              top: -15px;
                              left: 75px;
                              display:none;
                          }
                      
                          .mainmenu li:hover ul {
                              display:block;
                          }

Open in new window


All you need to do to make the menu support two levels is add an extra style to the existng hide and show styles for the second level of <ul> elements:
 
    .mainmenu li ul,
                          .mainmenu li:hover li ul {
                              //styles in here
                          }
                      
                          .mainmenu li:hover ul,
                          .mainmenu li:hover li:hover ul {
                              //styles in here
                          }

Open in new window


Can you see where I am going with this? Third level:
 
    .mainmenu li ul,
                          .mainmenu li:hover li ul,
                          .mainmenu li:hover li:hover li ul {
                              //styles in here
                          }
                      
                          .mainmenu li:hover ul,
                          .mainmenu li:hover li:hover ul,
                          .mainmenu li:hover li:hover li:hover ul {
                              //styles in here
                          }

Open in new window


For each level of menus, just add an extra style to the existng hide and show styles, by adding the last level's styles again to a comma delimited list and adding a "li:hover" at the beginning ^_^

6. Compatibility - A Coders Grief

Unfortunately, this menu is not compatible with IE6, as the CSS ":hover" style is only supported on the anchor tag (<a>). On later versions of IE (7 & 8) and other browsers the menu is working just right.

If anyone notes a bug or it is just simply not working for you, feel free to let me know via e-mail (psmarais@dropzone.com). (I just can't tollerate broken code on the internet, especially if I put it there)

Hope it helps ^_^

CSSMenu.txt
4
4,593 Views
Pieter MaraisSenior Developer
CERTIFIED EXPERT

Comments (5)

Pieter MaraisSenior Developer
CERTIFIED EXPERT

Author

Commented:
Hi lherrou,

Thanks for letting me know. I am assuming other users can't see the article. Would it be ok for me to update it a bit later in the week? I'm a little caught up in work at the moment.
Pieter MaraisSenior Developer
CERTIFIED EXPERT

Author

Commented:
Hi there,

I am really hung up on work right now, So it will be a while before I can shift my attention to this article. I'll try my best to get it ready though....

Thanks
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
Interesting article.  Nice tutorial and code for a CSS menu.

Does the dt tag have a role in the menu besides just the spacing?  Does it have to be that tag?  Without the dl tag the dt tag will most likely cause validation issues.  If you are using it for a tag so you can provide the style then I suggest the span tag instead.

Thanks for the article and work to provide it.

bol
Pieter MaraisSenior Developer
CERTIFIED EXPERT

Author

Commented:
Hi b0lsc0tt,

I did start of with the <span> at first, but then I changed it to the <dt> tag for some reason. I can't remember why... I need to document my reasons better.

But as you said, it would be better to use the <span> tag. I already tested it, and it seems that the menu still functions as expected.

Regards,
EZFrag

Commented:
Nice walkthrough for the unwary. There's one small addition I would recommend:
IE6 out of the box is not compatible but http://www.xs4all.nl/~peterned/csshover.html will solve this problem for you.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.