Need some help?

I'm usually available for small jobs or problem solving with jQuery or css, at reasonable rates. Just get in touch.

Web Hosting

We recommend Clook for web hosting. UK based, great service and great value.

Building a css vertical expanding menu with flyouts – stage 3

Click here for Part 2

First a word of warning. If by any chance you’re trying to follow this and using IE6, then first of all, it won’t work (but read on for a fix), and second of all, do yourself a big favour and install Firefox, or at least IE7.

The css changes here are quite simple.To create the “flyout” behaviour I’m going to use the concept of absolute positioning. This will enable me to use css to exactly define where I want the flyout menu to appear, outside the normal flow definded by the html.

I want to trigger this behaviour when the mouse is hovered over the appropriate top level menu button – so for example when I hover over the “Blog” menu button the second level menu should appear to the right of the Blog button, on top of any text.

I need to make two additions to the css to make this work:

css

#nav-menu ul
 {list-style-type:none;
  margin:0px;
  padding:0px}

#nav-menu ul a
{text-decoration:none;
 border:1px solid #303030;
 width:170px;
 display:block;
 text-align:center;
 font-size:14pt;
 line-height:2em;
 background:url(Images/Buttons/Button_top.gif) repeat-x left;
 font-family:Arial, Helvetica, sans-serif;
 color:white}

#nav-menu ul ul
{display:none} 

body.blog #nav-menu ul ul.blog, 
body.web #nav-menu ul ul.web
{display:block}

#nav-menu ul li{position:relative}

#nav-menu ul li:hover ul
{display:block;
 position:absolute;
 left:172px;
 top:0px;}

#nav-menu ul ul li a
{border:1px solid #888888;
 border-bottom: none;
 font-size:12pt;
 line-height: 1.6em;
 color:#303030;
 background-color:#a5a5a5;
 background-image:none;}

Let’s have a look at what I’ve done here. The statement

#nav-menu ul li{position:relative}

sets the reference point for my absolute positioning, in this case to be the position of the top level menu item. Once I’ve done this then the statement:

#nav-menu ul li:hover ul{display:block;position:absolute;left:172px; top:0px;}

displays the second level menu and positions it absolutely. Horizontally it’s positioned 172px to the left of the top level menu, accounting for the 170px width and a 1px border on both sides. Vertically it is positioned at the same height as the top level menu. So, from the Home page if I hover over “Blog” or “Websites” I get second level flyout. Give it a go below:

I’m not quite finished yet, because I don’t want a flyout menu if I hover over a top level menu on a page where I’m already displaying the second level menu. Sorting this out is quite easy using the classes I defined earlier. I just need to add to the css:

css

#nav-menu ul
 {list-style-type:none;
  margin:0px;
  padding:0px}

#nav-menu ul a
{text-decoration:none;
 border:1px solid #303030;
 width:170px;
 display:block;
 text-align:center;
 font-size:14pt;
 line-height:2em;
 background:url(Images/Buttons/Button_top.gif) repeat-x left;
 font-family:Arial, Helvetica, sans-serif;
 color:white}

#nav-menu ul ul
{display:none} 

body.blog #nav-menu ul ul.blog, 
body.web #nav-menu ul ul.web,
body.web #nav-menu ul li:hover ul.web,
body.blog #nav-menu ul li:hover ul.blog 
{display:block;position:relative;left:0px}

#nav-menu ul li{position:relative}

#nav-menu ul li:hover ul
{position:absolute;
 display:block;
 left:172px;
 top:0px;}

#nav-menu ul ul li a
{border:1px solid #888888;
 border-bottom: none;
 font-size:12pt;
 line-height: 1.6em;
 color:#303030;
 background-color:#a5a5a5;
 background-image:none;}

What the css is saying here is that when I’m hovering over, for example “Blog” but on a page with class of “blog” then the second level menu should be positioned as normal, not as a flyout. This will take precedence over the earlier statement because it specifically applies to the blog page.

So, if you’re designing for IE7+, Firefox, Opera, Chrome or Safari, that’s all there is to it.

Sadly, however, some (most?) people need to take IE6 into account. This will not work on IE6 without a tweakette because IE6 does not support the hover behaviour except on links. There is a little widget that will take care of this however, called csshover, which you’ll find here along with instructions on how to use it. I’ve personally found version 2 of this software to be the most reliable.

If you’ve got this far, I hope you’ve found these few pages useful. If you’ve got any suggestions for improving either the css or the article, let me know.

15 responses to “Building a css vertical expanding menu with flyouts – stage 3”

  1. Simon says:

    If you don’t want it to fly out I’m not sure what you want it to do, but the flyout bit is handled by this:

    #nav-menu ul li{position:relative}

    #nav-menu ul li:hover ul
    {display:block;
    position:absolute;
    left:172px;
    top:0px;}

    If the menu is identical on all pages then you can ignore the last section of code on the stage 3 page, as this is giving a different behaviour (in the example) to pages with class of blog.

  2. Lensmeister says:

    Hi,
    Been following and loved this.
    I don’t need the menu to fly out at all as it will overlap the main section in column two. What do I need to leave out?
    Also I would need the menu to be the same on all pages (The html will be contained within a menu.php that included) so not different on different sections/pages. What can I leave out?

    THanks for a great tutorial.

  3. George says:

    Simon,

    I am not a great web coder but did a bit of Pascal back in the day. Mostly fiddling with PHP these days.

    I was able to cobble your flyout menus into my church’s site and am relatively pleased. I could not find the button .gif, so my menus are pretty Plain Jane. The good news is I shortened the “list” of pages by using hierarchal structure.

    Anyway, I wanted to thank you for putting this together for those of us who are puzzled by css, java, php, html mixtures. The one thing I did not understand is that the css needed to be in the header contained in <> (I know, the first S in CSS should have tipped me off!) so for a while the css text was appearing on my page with no button action. Not a big problem and I will remember this in the future.

    Thanks again.

  4. Simon says:

    Hi Greg
    Thanks for your comments. Setting margin-top should do the trick. This alone wouldn’t cause your links to stop working – that suggests perhaps that some other element on the page is sitting on top of the links and preventing clicks. If you post a link to your page there’s probably a fairly simple fix.

  5. Greg says:

    Excellent tutorial. I’m a beginner in the CSS realm. Is there a way of dropping the top of the menu down? I’ve tried but when I add a margin:120px 0px 0px 0px to the menu, it will drop the menu down however, the links stop working. I’ve learned alot from this tutorial, thank you.

  6. Coleen says:

    I use fluid 3-column layout using all CSS and at first, this was not working correctly because in my 3-column layout I had the overflow:hidden. so the second level fly-out was being chopped off at the width of the column. It was an easy fix to change the overflow to visible and now the columns and fly-out menus all work correctly – thank you for this tutorial!

  7. Simon says:

    Glad it worked for you.

  8. Thanks for the great tutorial.
    I’ve used it on my website. But it also changed somewhat. Still working.
    I have the position in the # nav-menu ul li: hover ul of absorlute and relative to the left: 100%; 0px to;.And i let out the body.blog etc.
    The result is amazing. Exactly what I was looking for. When you consider that I have found it by accident. I ‘m No CSS expert.

    Look yourself in …

  9. Linda says:

    Thanks for the quick response! That is exactly what I needed!

  10. Simon says:

    If you’re not worried about IE6 then you should just be able to change this css:

    #nav-menu ul li:hover ul {
         display: block;
         left: 100%;
         position: absolute;
         top: 0pt;
         z-index: 10;
    }

    to this

    #nav-menu ul li:hover > ul {
         display: block;
         left: 100%;
         position: absolute;
         top: 0pt;
         z-index: 10;
    }

    , using the immediate child selector, and it should be OK. If you are worried about IE6 then you need to explicitly prevent the third level menu being displayed on the first level hover.

  11. Linda says:

    can you tell me how I would add another level of submenu? For example, under Websites–> Websites 1–>Websites 1a

  12. Abby says:

    This is exactly what I was looking for! Thank you so much for sharing!

  13. David James says:

    Brilliant! was just what I needed and very well explained. Most well written and understandable tutorial I have read.

  14. Raziel says:

    Very well explained. I was looking for a expandable vertical CSS menu and this is, by far, the best building example I’ve seen.

    Thank you for sharing.

    Regards
    Raz

  15. c smith says:

    Thank You So Very Much!!
    Excellent website!!
    Excellent css flyover examples and instructions!!!

    Bravo…wonderful … THANK YOU!!!

Useful? Interesting? Leave me a comment

I've yet to find a way of allowing code snippets to be pasted into Wordpress comments - so if you're trying to do this you'd be better off using the contact form.