Creating Simple CSS Menus without Javascript

AID: 678
  • Status: Published

7200 points

  • ByEZFrag
  • TypeTutorial
  • Posted on2009-05-22 at 17:30:06
Awards
  • Community Pick
  • Experts Exchange Approved
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">
                                    
1:

Select allOpen 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>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:

Select allOpen 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>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:

Select allOpen in new window



3

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>
                                    
1:
2:
3:
4:
5:
6:
7:

Select allOpen 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;
    }
                                    
1:
2:
3:

Select allOpen 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;
    }
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen 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;
    }
                                    
1:
2:
3:
4:
5:
6:

Select allOpen 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;
    }
                                    
1:
2:
3:
4:
5:
6:
7:

Select allOpen 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;
    }
                                    
1:
2:
3:

Select allOpen 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;
    }
                                    
1:
2:
3:
4:
5:
6:
7:
8:

Select allOpen 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;
    }
                                    
1:
2:
3:

Select allOpen 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>
                                    
1:

Select allOpen 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;
    }
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:

Select allOpen 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;
    }
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen 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
    }
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:

Select allOpen 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
    }
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:

Select allOpen 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
  • 1 KB
  • Full Version HTML Of Completed tuturial
CSSMenu.txt
    Asked On
    2009-05-22 at 17:30:06ID678
    Tags

    css

    ,

    menu

    ,

    html

    Topic

    Miscellaneous Web Development

    Views
    1825

    Comments

    Author Comment

    by: EZFrag on 2009-05-25 at 00:45:34ID: 1117

    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.

    Author Comment

    by: EZFrag on 2009-06-01 at 05:49:05ID: 1263

    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

    Expert Comment

    by: b0lsc0tt on 2009-07-06 at 15:38:12ID: 1938

    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

    Author Comment

    by: EZFrag on 2009-07-07 at 00:40:37ID: 1941

    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

    Expert Comment

    by: mreuring on 2010-09-08 at 10:21:52ID: 19191

    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.

    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 Misc Web Dev Experts

    1. COBOLdinosaur

      144,341

      Master

      0 points yesterday

      Profile
      Rank: Genius
    2. Ray_Paseur

      142,428

      Master

      3,800 points yesterday

      Profile
      Rank: Savant
    3. jason1178

      102,330

      Master

      0 points yesterday

      Profile
      Rank: Genius
    4. DaveBaldwin

      76,853

      Master

      2,200 points yesterday

      Profile
      Rank: Genius
    5. ve3ofa

      50,168

      Master

      0 points yesterday

      Profile
      Rank: Genius
    6. nap0leon

      45,060

      0 points yesterday

      Profile
      Rank: Sage
    7. mplungjan

      45,026

      0 points yesterday

      Profile
      Rank: Savant
    8. leakim971

      33,300

      0 points yesterday

      Profile
      Rank: Genius
    9. ChrisStanyon

      28,132

      0 points yesterday

      Profile
      Rank: Sage
    10. tommyBoy

      26,968

      0 points yesterday

      Profile
      Rank: Genius
    11. Tiggerito

      26,204

      0 points yesterday

      Profile
      Rank: Sage
    12. kozaiwaniec

      19,800

      0 points yesterday

      Profile
      Rank: Guru
    13. shalomc

      19,268

      0 points yesterday

      Profile
      Rank: Genius
    14. LZ1

      17,720

      0 points yesterday

      Profile
      Rank: Genius
    15. webmatrixpune

      17,668

      0 points yesterday

      Profile
      Rank: Guru
    16. padas

      16,992

      2,000 points yesterday

      Profile
      Rank: Wizard
    17. sammySeltzer

      16,568

      0 points yesterday

      Profile
      Rank: Genius
    18. Gertone

      16,100

      0 points yesterday

      Profile
      Rank: Genius
    19. hielo

      15,700

      0 points yesterday

      Profile
      Rank: Savant
    20. singleton

      14,400

      0 points yesterday

      Profile
      Rank: Guru
    21. kaufmed

      14,376

      0 points yesterday

      Profile
      Rank: Genius
    22. paulmacd

      13,998

      0 points yesterday

      Profile
      Rank: Genius
    23. StingRaY

      13,668

      0 points yesterday

      Profile
      Rank: Wizard
    24. ahoffmann

      13,608

      0 points yesterday

      Profile
      Rank: Genius
    25. sudaraka

      13,000

      0 points yesterday

      Profile
      Rank: Sage

    Hall Of Fame