Pure CSS Vertical Menu
Today we are going to build the second most common menu navigation, the vertical navigation menu. Here we are going to be using only pure CSS and un-ordered lists to create our vertical navigation menu with three levels of pop outs. This version of the vertical navigation menu will work in IE5, IE6, IE7 and IE8 as well as FF and Safari.
Let’s begin shall we. To start lets create our menus container block and give it an id of “navigation”.
<div id="navigation"> </div>
Next we will add our first level menu items.
<div id="navigation">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
After this we are going to give our list items some names.
<div id="navigation">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
<li>FAQ</li>
<li>News</li>
</ul>
</div>
Great let’s see what we have so far.
Obviously it’s not going to work for us, but I think it’s important to point out that the vertical fashion that is given to us by default in the ordered list is here to help us. The vertical menu and un-ordered list almost seems to be a match made in CSS heaven vs. its sister menu the horizontal navigation menu.
So let begin to add some style to our first level un-ordered list and its parent container “navigation” shall we.
In our header we create some style tags that will contain all our CSS. Our first CSS rule we want to add would be for our container.
<style type="text/css">
#navigation {width:150px; font-size:12px;}
</style>
Here we are going to give our main container some structure by setting its width to 150 pixels; we also set our menus font size to that of 12 pixels that will cascade down our entire menu.
Great next we are going to create a rule for our first level un-ordered list.
<style type="text/css">
#navigation {width:150px; font-size:12px;}
#navigation ul {margin:0px; padding:0px; background-color:#666;}
</style>
Ok here we are pointing to our “navigation” container first, then our first un-ordered list and assigning styles accordingly. We have removed the default margin and padding that comes with a un-ordered list by setting both to 0 pixels. For style sakes we set our first un-ordered list’s background color to # 666.
Ok let’s see what we have so far.
Again not looking to hot right now, but we will get there. Our next step is to assign some styles to our un-ordered list items. We do this by again pointing to our “navigation” container; its first un-ordered list, and then our list items.
#navigation {width:150px; font-size:12px;}
#navigation ul {margin:0px; padding:0px; background-color:#666;}
#navigation ul li {
height:25px;
line-height:25px;
list-style:none;
padding-left:10px;
color:#FFF;
border-top:#fff solid;
border-bottom:#fff solid;
border-width:1px;
cursor:pointer;
}
Ok here we have a lot of styling to give to these list items that will cascade down our entire menus look and feel for the rest of the menus list items. So to begin we remove our default un-ordered list item styles, or rather bullets next to each list item. Next we set a height of 25 pixels to space our list items out vertically a little, but at the same time make up for text placement by using the line-height and left padding.
For the line-height, we set it exactly the desired height of the list item in order to center our text vertical within the list item. Our padding-left style is to move each list items text off the left site by 15 pixels. Our last CSS styles are purely for preference and deal with border colors and thickness, font color and cursor types. These last styles may also change according to your design.
Let’s take a look shall we.
Ok not too bad.
Before we move onto creating our second level sub menu, lets add some behavior to our menu shall we. Let’s give a color difference to our list items background color if we are hovering over them.
To do this we again reference to our “navigation” container first, then our first un-ordered list and then our list items them self. Once we are pointing to our menus list items we add a pseudo hover to begin the statement for our behavior.
#navigation {width:150px; font-size:12px;}
#navigation ul {margin:0px; padding:0px; background-color:#666;}
#navigation ul li {
height:25px;
line-height:25px;
list-style:none;
padding-left:10px;
color:#FFF;
border-top:#fff solid;
border-bottom:#fff solid;
border-width:1px;
cursor:pointer;
}
#navigation ul li:hover {background-color:#F90; position:relative;}
Here we are giving our list items a background-color of #F90 and set its position to be that of “relative”. We use relative because it turns our list items into stopping points for any immediate children that have a position of absolute vs. having the absolute element break out of our menu all together. We also get the position of relative to our list items here at the hover state in order to fix IE related issues.
Ok so here is what our menu behavior looks like.
Ok now we must move into our second level un-ordered list. We always nest our sub menus deeper within the list item we want it to be displayed under.
So make your HTML look like the following:
<div id="navigation">
<ul>
<li>Home
<ul>
<li>Sub Menu Item 1</li>
<li>Sub Menu Item 2</li>
<li>Sub Menu Item 3</li>
<li>Sub Menu Item 3</li>
</ul>
</li>
<li>About</li>
<li>Contact</li>
<li>FAQ
<ul>
<li>Sub Menu Item 1</li>
<li>Sub Menu Item 3</li>
</ul>
</li>
<li>News
<ul>
<li>Sub Menu Item 1</li>
<li>Sub Menu Item 2</li>
<li>Sub Menu Item 3</li>
</ul>
</li>
</ul>
</div>
Ok notice how we have added entirely new un-ordered lists to our first level list items we want a sub menu to appear. Great let’s move back up to our CSS and begin to set some visual rules to these second level un-ordered lists.
To give ruling to these second level un-ordered lists we again must traverse past our “navigation” container to our first level un-ordered list and then to our second un-ordered list like so.
#navigation ul ul {
display:none;
position:absolute;
left:75px;
top:5px;
border:#fff solid;
border-width:1px;
background-color:#999;
}
Here we are giving our second un-ordered list a display of none. We do this so that by default, our second level un-ordered lists are hidden until told so. Next we set our second un-ordered list to be a position of absolute so we may position it according to the location of its parent relative element. To position our absolute second level un-ordered lists we use the top and left styles. Our last styles are of preference and are for borders, border widths and background colors and may change in your design.
Ok so we have written our second level un-ordered list’s off behavior state so we now have to write our display behavior state. To do this we point to the first level un-ordered list and instate a pseudo hover. Next we point to our second level un-ordered list and give a display of block to display it out upon its parent being hovered, like so.
#navigation ul ul {
display:none;
position:absolute;
left:75px;
top:5px;
border:#fff solid;
border-width:1px;
background-color:#999;
}
#navigation ul li:hover ul {display:block;}
Great just a few more rules and styles are we are complete.
Ok the last two CSS rules for our second level un-orderd list are primarily for structure purposes only. The first rule points to all our second level un-orderd list items and real estates the overall width of 150 pixels to reassure that our sub menu and its items will carry the same width as our overall menu. Next we set a float of left and a display of inline to fix any IE related issues. Finally for personal likes I removed our previously stated border from the second un-orderd list items.
#navigation ul ul {
display:none;
position:absolute;
left:75px;
top:5px;
border:#fff solid;
border-width:1px;
background-color:#999;
}
#navigation ul li:hover ul {display:block;}
#navigation ul ul li {border:none; width:150px; float:left; display:inline;}
The next, and last rule for the second level un-orderd list is for visual purposes only and adds a pseudo hover behaviour to all our second level un-orderd list items. Here we are giving our list items a text decoration of underline and removing any border from list items.
#navigation ul ul {
display:none;
position:absolute;
left:75px;
top:5px;
border:#fff solid;
border-width:1px;
background-color:#999;
}
#navigation ul li:hover ul {display:block;}
#navigation ul ul li {border:none; width:150px; float:left; display:inline;}
#navigation ul ul li:hover {text-decoration:underline; border:none;}
Let’s look at what we have so far.
Now let’s create our last level un-ordered list. Like before we are going to insert a new un-ordered list and items with in the level and list item we want to trigger or rather pop out this third level un-ordered list.
Here is what our final HTML would look like.
<div id="navigation">
<ul>
<li>Home
<ul>
<li>Sub Menu Item 1</li>
<li>Sub Menu Item 2
<ul>
<li>Sub Sub Menu Item 1</li>
<li>Sub Sub Menu Item 2</li>
<li>Sub Sub Menu Item 3</li>
<li>Sub Sub Menu Item 4</li>
</ul>
</li>
<li>Sub Menu Item 3</li>
<li>Sub Menu Item 3</li>
</ul>
</li>
<li>About</li>
<li>Contact</li>
<li>FAQ
<ul>
<li>Sub Menu Item 1</li>
<li>Sub Menu Item 3
<ul>
<li>Sub Sub Menu Item 1</li>
<li>Sub Sub Menu Item 2</li>
<li>Sub Sub Menu Item 3</li>
<li>Sub Sub Menu Item 4</li>
</ul>
</li>
</ul>
</li>
<li>News
<ul>
<li>Sub Menu Item 1
<ul>
<li>Sub Sub Menu Item 1</li>
<li>Sub Sub Menu Item 2</li>
<li>Sub Sub Menu Item 3</li>
<li>Sub Sub Menu Item 4</li>
</ul>
</li>
<li>Sub Menu Item 2</li>
<li>Sub Menu Item 3</li>
</ul>
</li>
</ul>
</div>
Great, because we have already stated most visual styles we want our menu to carry, these last few rules and styles are for structure only. To start we add a reset rule if you will, that will basically prevent our third level un-ordered list from being displayed until its proper parent and un-ordered list level has been hovered over. In other words, we don’t want our third level un-ordered list to be displayed when our first level un-ordered list is being hovered over but rather display it’s self only when our second level un-ordered list is hovered.
Here is what this reset would look like.
#navigation li:hover ul li ul {display:none;}
Great let’s move onto the last few rules. Our first one is to offset our third level un-ordered list to the left further than its parent un-ordered list level. So again point to our third level un-ordered list and give it a left style of 110 pixels. I also added a different color background color here for kicks and to demonstrate you can define styles even further if you wish.
#navigation li:hover ul li ul {display:none;}
#navigation ul > ul > ul > ul ul li ul {left:110px; background-color:#0099CC;}
Ok now we already created a reset rule that would keep our third level un-ordered list from being displayed, let’s crate our last rule that will finally display our third level un-ordered list out.
#navigation li:hover ul li ul {display:none;}
#navigation ul > ul > ul ul li ul {left:110px; background-color:#0099CC;}
#navigation ul > ul ul li:hover ul {display:block;}
Great so here we point all the way down to our second level un-ordered list and assign a pseudo hover behavior to it. We then move onto pointing at the third level un-ordered list and set a display of block.
Let have a look-see at what our vertical menu now looks like shall we?
Thats it everyone, you have just created a pure CSS vertical menu with sub level pop outs that is completely cross browser friendly.
Here is a working example of the pure CSS vertical menu
PLEASE NOTE: The above example works in IE5 and IE6 because of the pseudo-hover fix that can be found here. Please read this pseudo-hover fix tutorial if you are trying to get this or even the Pure CSS Horizontal Menu to work in older versions of IE.
[IF YOU WANT AN INFINITE AMOUNT OF SUB MENUS PLEASE REFER TO THIS TUTORIAL.]
Thanks everyone.
Devin R. Olsen







Good work Devin.. Looks like you have knack for explaining things in a simplistic manner!! Keep up the work.
I am looking for a pure css vertical menu which is expandle ie levels expanding rather than poping out.
Excellent tut man! sorted me out in no time =)
good work
OMG! thank you!
@Pardeep kumar Dhiman – I think you are saying that the content is being displayed over your menus when they pop out?
If this is the case, it sounds like you might need to set your menus absolute parent element to have a z-index higher than that of your contents parent element.. I would need a link to further help you.
Respected Sir
Thank U very Much For This Tutorial.
I am facing a problem.In Home page of my Web Site in Left 25% area is vertical menus and in the rest of the area i have content panel for Content .When I hover the First Level Menu Then Its Child Went Upon the Content in the Content Panel and The content Panel Content is Displayed Inseted of the Menu Heading. Suggest Solution early
Thanks so much! This works perfectly and with little effort. It is just what I needed.
Great Tips…. Thanks
@Kevin – With out an example link of what you are working on this is hard to visualize. However I see the word “click-able”, and right off the bat this tells me that you are looking for a JavaScript method to display or hide sub menus, not CSS.
Hover = CSS selector and is equivalent to JavaScript mouse over event.
Click = JavaScript Event and not CSS at all.
Also note, that Java and JavaScript are two different things. JavaScript is a client side language and does not rely on web servers support.
Hello Devin,
Your code works perfectly! I have adapted it a little bit. The menu expands directly under the headermenu. i.e. menu 1 items show directly under menu 1, in the space between menu 1 and 2. The only problem I’m facing now is that I need to make the whole area of a button clickable to make sure they stay focused.
Example, mouse pointer stands on menu 1, menu 1 extends, I want to hover to menu 4 but the second menu 1 loses focus it collapses and I need to move the mouse up to view menu 4. This is annoying for visitors.
Can you think with me and come up with a solution? I’ve tried to turn my headermenu’s into a href but that doesn’t solve it, since the a href doens’t cover the whole headermenu area which is clickable.
(Java isn’t a solution since my server doesn’t support it)
@shaila – I would need more information about what you mean by linking. Do you mean you are having a problem adding <a href=”YOURURL”>YOUR LINK TEXT</a> link to your menu items?
@Stephen & @Mike – Yes I can, http://www.devinrolsen.com/pure-css-menu-with-infinite-sub-menus-tutorial/
This will show you how to have an infinite amount of sub menus with very lightweight pure CSS!
[...] 5. Pure CSS Vertical Menu [...]
Nicely done!.
I’ve used all these codes on my already put up website!
Thanks for sharing these codes, i hope there’s more codes that i get to thank! :)
Sir i am facing problem in linking this menu to other webpages can u plz help me out
Hello,
I want to use your CSS based menu on my new sites I am building at the moment. The menu does not work because I use as a starter line. I need this for the streched backgrounds in the header and menu. Do you have a solution for this?
regards
Benny
hi friends,
this css is very much helpful for creating vertical menu without java script. i really thanks to Devin R. Olsen. and can you help me, how to add more than three sub menus?
thanks and regards
stephen s
Was desperately trying to get the positioning of my vertical navigation bar right before a deadline – your article got me there – thank you :-)
Perfekt! muss auch so was schönes ausprobieren. Danke :)
Muchas gracias por este manual tan bien explicado. Me cayo como anillo al dedo.
This is sublime, but I am having a problem moving the whole thing about the page- it’s locked to top-left position, and it seems I can’t change it… Am I missing something or am I not understanding what tags I must use?
Thank you, by the way, for posting this… albeit the small issue I’m having, this has been of exceptional help.
Hi,
I very much like your Pure CSS Vertical menu example.
I have a question!
My menu is quite long and has a large number of 3rd level options so when the menu is expanded they unfold below the screen out of view, so you need to use your mouse wheel to bring them into focus. I can see that these are shown as “absolute”, is there a way of keeping them in view “without the use of Java”?
Thanks.
Mike
Nice tuition, and cool display of feedback !
I have integrated it in facebook but it does not work.
What a great tool for the rest of us to learn quickly!
I made a few changes successfully and still trying to change the underlined blue text to regular black. Any suggestions how to do that? I added “COLOR:#0000; TEXT-DECORATIO: none;” to every line and still not able to get it right.
Wow! Thanks. Great stuff. I’m using this CSS Vertical menu in my current project and look forward to coming back for other tutuorials.
Would you share what development environment you use? Looking at the code screen shots on other tutorials, the code looks well colored, easy to follow.
I will used :)
@Lt. D. Young,
Sounds to me like you need to give the anchor a “display:block;” style. By telling the anchor tag to behave like a block you can use “with:100%;” like you would with block like elements.
Hope this helps.
First, Great tutorial. Was able to grasp the concept within the first 10 minutes of analyzing. Now, I have run into a problem that I may need assistance with. The li:hover works great, until I add an anchor tag. I’ve gotten it to effect the font color change on hover, but only if you hover over the verbage itself. I’m trying a span for the width of the div & li – however to no avail. I know it has to be something very simple, as I have done it with a horizontal nav bar. I tried to merge the two sets of css, but i have run out of ideas. (not great for someone who’s been designing for 15+ years, eh?)
Please Advise.
Cordially,
Lt. D. Young
Great article, very easy to follow.
…please where can I buy a unicorn?
You have used “display”none” property and seo expert say hiding text using css is not advisible.
Very nice thanks a lot!!! I’m big fan your site
Nice tutorial, I learned some new tricks.
I used div’s instead of ul’s (I don’t really like ul’s) still your design man, thanks.
Absolutely as long as there is a link back I dont mind at all.
Hello from Russia!
Can I quote a post in your blog with the link to you?
In IE6 This Menu not Working
Easy to understand and learn.
thank you.
Dear author,
You just made my day. Thank you so much for this tutorial.
This tutorial helps a lot and probably the simplest to follow YET the BEST on the internet.
Thank you.
awesome man, exactly what I needed
http://www.devinrolsen.com – da best. Keep it going!
Bodyc
ok hi again,
I just found something out; in safari the sub is horizontal (preferable) and I checked another page in firefox and there it is vertical! How can i change it to horizontal?? (in the css)
Cheers Vincent
Hi, tnx for the great tutorial! I implemented it and it works great with safari, although I expected it to roll down instead of a horizontal menu, I am happy with it though.
But , when I checked it in Mac Firefox I see only the first submenu item. Any idea how to solve this
Many thanks
Vincent
Hi Susan, the code is correct. The problem was one of the example images was out of place. Please have another stab at the step by step tutorial again. I just went from start to finish and the end result was how it should be now.
Also note, each level of the menu is broken into chunks of code, we go over each chunk of code one rule at a time. Each new rule to each chunk of code is bolded to give relevance over this rule(s) we are talking about.
The wrong css code appears after this paragraph:
“To do this we again reference to our “navigation” container first, then our first unordered list and then our list items them self. Once we are pointing to our menus list items we add a pseudo hover to begin the statement for our behavior.”
It’s the same as the one before.
Would love to finish this tutorial.
Easy to use & good in look
Dude this is great!
I wish the link for the working example was valid :(
I always enjoy feedback from my readers.
great tutorial ,thank you so much
Nice tutorial, really learned something out of it. thx great!
nice
nice tutorial.. simple but helpfull.. thx..
Hello Devin. Think your website is excellent, one of the best tutroial website around the world. Great tutorials and excellent manner at explaining things. Keep up the good work All the best from Josh
Well thank you very much Josh. I have worked really hard at trying to provide only the basic fact here to my readers and will continue to do so. I know my updates to this site have slowed just a little due to work and another huge project I plan to release soon. With that said though I will be releasing a whole array of new tutorials here shortly, so stay tuned everyone.
can you give the link whrere I can download the cssHoverFix.htc for IE.
hey devin thanks fot this script but dude your css not work on ie6.
plz check it on ie6 and sent me revert back on my email id
singh.is.sandeep@gmail.com
sandeep In order to make either horizontal or vertical menus to work you must read my \”CSS IE Hover Fix\” tutorial for IE5 and IE6.
joney, you can download a copy of the cssHoverFix.htc at my \”CSS IE Hover Fix\” tutorial under tutorials pull out up top.
clean and simple, I appreciate the tutorial :-D
I remove the height on css so that when I have a long title menu it will move on the next line.My only problem when I hover on the blank space on first level the second menu didn’t show but when I hover it on the menu title it works. I got this problem on IE 5.5 and 6.
Cheers Devin! A tweak here and there, and its exactly what I was after. Thanks again.
nice job dear. its excellent.
Absolutely fantastic tutorial. Thank you very much.
good job……… thanx
Great menu Devin, Worked perfectly on ie6 for me
Devin. Outstanding work! I do have a problem on IE7. The third level reset only works once or twice when hovering over the first level. Then, when I hover over the first level again, the third level pops up, but with no links. Just the blue block. It then continues to do this until I refresh the page. Any hints? Thanks, frank.
Walaka, English please :)
nice job dear, thanx
Perfect example, just what I was looking for, thank you :-)
how to make more than 3 vertical drop down menus
cool menu without javascript;)
i learn a lot!!!
nice teaching……… thank u for spending ur time for this tutorial
Devin� Your code is really useful to me… I have one query… I have created the menu plus one submenu in the first cell of the table. In the next cell I have embedded one flas picture. If I move upon the menu now, the submenu gets hided behind the flash… Is there any solution to this….
i got it! thanks u very much!
If I want to add the second vertical menu on the right of the web page then how can I do that?
Very great and Detailed explanation, thanks alot
It’s not a menu until you actually add some links. I find it better if the whole cell is a link rather than just the text – how would you do this?
Very nice thanks a lot!!! just wish there was a css function \”click\”!!
walaka yeh tum kia karti hai