Transforming unsorted list into CSS horizontal menu
Lately I’ve been working on the new cool theme for BlogEngine that I’m going to share with community. One of the tasks is to let it be more content oriented, which is a bit different then other themes. Basically, it comes down to having good navigation menu that will allow you to utilize stand-alone pages in BlogEngine to its full potential. Currently, you have a choice to make page a “child” of the other page so that pages do have hierarchy and can be nested into the tree-like structure. It just not rendered by BlogEngine this way, at least not right now. To make it happen I used code published on the BlogEngine forum, just making a few changes to fit my needs. This is a simple control that looks inside core library and renders all BlogEngine pages into unsorted list. Then, you can just add it to your theme and here you have it:
In some cases, that’s enough. You just add style sheet to make list look pretty and you done. This approach has its own advantages; everything is just one click away. On the other hand, it takes lots of space and if you have large content hierarchy that is not an option. You probably need full blown horizontal menu with pull down submenus. Horizontal menus are slim, they do not take much space and users are used to this kind of navigation. So the task is to transform UL to the horizontal menu, as you can see on the left picture.
Then, when user hovers over the top menu, we show sub menus and, if sub menu has children, hovering over it will show sub-sub menus and so on. Normal stuff, every web user saw it and used it and takes for granted. It is possible to achieve this behavior with pure CSS using some voodoo magic, but let’s not go there. Actually, it is easier to do combining CSS with javascript. All that needs to be done – hide all submenus on load and show them when parent node triggers mouse over event. All CSS is doing is lining up items using typical layout tricks. You can see here how it all works.
The entire code for this page is shown below. Not too exiting yet, but ones you get that far - it is all down the hill from here. Next time I’ll cover how to make it look good and run inside BlogEngine (or DotNetNuke – same rules applied).
<html>
<head>
<style type="text/css">
#navmenu li{
white-space:nowrap;
position: relative;
display: inline;
float: left;
margin: 0 15px 0 15px;
}
#navmenu li ul{
position: absolute;
top: 1.1em;
display: block;
list-style-type: none;
padding: 0;
margin: 0;
left: 0;
visibility: hidden;
}
#navmenu li ul li{
display: list-item;
margin: 0;
padding:0;
float: left;
}
</style>
<script type="text/javascript">
function buildsubmenus\_horizontal(){
var ultags=document.getElementById("navmenu").getElementsByTagName("ul");
for (var i=0; i<ultags.length; i++){
ultags[i].parentNode.onmouseover=function(){
this.getElementsByTagName("ul")[0].style.visibility="visible"
}
ultags[i].parentNode.onmouseout=function(){
this.getElementsByTagName("ul")[0].style.visibility="hidden"
}
}
}
if (window.addEventListener)
window.addEventListener("load", buildsubmenus\_horizontal, false)
else if (window.attachEvent)
window.attachEvent("onload", buildsubmenus\_horizontal)
</script>
</head>
<body>
<br>
<ul id="navmenu">
<li><a href="#">Top One</a></li>
<li><a href="#">Top Two</a>
<ul>
<li><a href="#">Sub One</a></li>
<li><a href="#">Sub Two</a></li>
</ul>
</li>
<li><a href="#">Top Three</a></li>
</ul>
</body>
</html>