Create a CSS drop-down menu with persistent active state
Yesterday at work I stumbled upon an idea that I haven’t seen before when dealing with pure CSS drop-down menus. The general premise is to use an unordered list within an unordered list activated on hover of the parent li. This is pretty standard (but won’t work in IE6 due to hovers only being available on anchor tags) and was no problem to implement:
The HTML
<ul id="menu">
<li><a href="#item1">Menu Item 1</a></li>
<li><a href="#item2">Menu Item 2</a>
<ul>
<li><a href="#sub1">Sub Menu Item 1</a></li>
<li><a href="#sub2">Sub Menu Item 2</a></li>
<li><a href="#sub3">Sub Menu Item 3</a></li>
</ul>
<li><a href="#item2">Menu Item 3</a>
</ul>
The CSS
ul#menu {list-style:none;}
ul#menu li {display:inline; float:left; width:200px;}
ul#menu li a {background:#CCCCCC; display:block; padding:5px 10px; text-align:center; text-decoration:none;}
ul#menu li a:hover {background:#333333;}
ul#menu li ul {display:none; position:relative;}
ul#menu li:hover ul {display:block;}
ul#menu li ul li a {background:#333333;}
ul#menu li ul li.overlay {position:absolute; top:-26px; left:0;}
The problem?
The problem you will notice is that as soon as you start to hover over the sub menu items, the main menu item returns to it’s native, non-hover state. This is a problem as this affects the aesthetic quality of the menu and goes against the expected action.
The solution
The idea I had to solve this problem was to add anextra list element at the top of the sub menu unordered list and absolutely position it over the item on the main menu when the cursor hovers over the sub menu. Again this action is only supported by IE7 and above.
- The list item will have a class ‘overlay’ applied to it so as it can be uniquely identified.
- The list item will have the same text and same link destination as the main menu item.
- position:relative; needs to be added to the sub menu unordered list in order to add position:absolute; to the class ‘overlay’
- The position of the class ‘overlay’ needs to be the negative value of the sub menu list items. So if your list items are 20px in height, the class ‘overlay’ needs to have top:-20px; applied to it.
- For some reason float:left; needs to be applied to the sub menu unordered list for the effect to work properly in IE7.
Have a look at the code below and check out the demo
The HTML
<ul id="menu">
<li><a href="#item1">Menu Item 1</a></li>
<li><a href="#item2">Menu Item 2</a>
<ul>
<li class="overlay"><a href="#item2">Menu Item 2</a></li>
<li><a href="#sub1">Sub Menu Item 1</a></li>
<li><a href="#sub2">Sub Menu Item 2</a></li>
<li><a href="#sub3">Sub Menu Item 3</a></li>
</ul>
</li>
<li><a href="#item3">Menu Item 3</a></li>
</ul>
The CSS
ul#menu {list-style:none;}
ul#menu li {display:inline; float:left; width:200px;}
ul#menu li a {background:#CCCCCC; display:block; padding:5px 10px; text-align:center; text-decoration:none;}
ul#menu li a:hover {background:#333333;}
ul#menu li ul {display:none; position:relative; float:left;}
ul#menu li:hover ul {display:block;}
ul#menu li ul li a {background:#333333;}
ul#menu li ul li.overlay {position:absolute; top:-26px; left:0;}
This is the basic principle. View the demo to see it with some styling.
Please feel free to comment with any improvements or criticisms.
