Usability and a Simple JavaScript hovering menu

Many web developers ask ‘what is usability?’. This is one of those topics that I can explain, but it may be easier to demonstrate. My this experiences have led to some principles; one of them is that if I’m going to build it, it must be usable. Unfortunately, many sites that I like, that tout usability, screw up one important concept that annoys me greatly.

I ask myself, “when using a menu, why do I have to drag my mouse from one button to the next, and fear losing the menu if I cross it’s border anywhere?” Some menus are just annoying because they disappear mid mouse move, some are extremely hard to use because of several layers of menus, some I have resorted to using tabs to get to the correct menu item. It’s unfortunate that people can’t get this right.

I have a simple fix that hopefully sharing it will help others. It’s basically a menu that buffers the time you are hovering, that way if you mistakenly move your mouse into the wrong area, you have a brief period of time to correct yourself.

Start with the HTML code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<ul id='menu'>
<li class='nav'><a><span>ONE</span></a>
<ul>
<li><a><span>one</span></a></li>
<li><a><span>two</span></a></li>
<li><a><span>three</span></a></li>
<li><a><span>four</span></a></li>
</ul>
</li>
<li><a><span>TWO</span></a></li>
<li class='nav'><a><span>THREE</span></a>
<ul>
<li><a><span>one</span></a></li>
<li><a><span>two</span></a></li>
<li><a><span>three</span></a></li>
<li><a><span>four</span></a></li>
</ul>
</li>
<li class='nav'><a><span>FOUR</span></a>
<ul>
<li><a><span>one</span></a></li>
<li><a><span>two</span></a></li>
<li><a><span>three</span></a></li>
<li><a><span>four</span></a></li>
</ul>
</li>
</ul>

The menu is a simple list within a list. There are essentially only four main list items; ONE, TWO, THREE and FOUR. Each of this list items has their own list of list items generically named one, two, three and four. I personally stick with lists as my menu’s of choice because they degrade gracefully in case of CSS/JavaScript issues.

This list by itself isn’t much, in fact it’s not even a menu. CSS will be needed to really make it work correctly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#menu li {
list-style:none;
float:right; /* Makes IE 6,7,8 act like FF */
position: relative;}
#menu li a {
display:block;
width: 160px;
height:35px;
margin-top: 5px;}
#menu li a span{
padding-left:10px;
line-height:2.8em;
color: #000000;
font-weight:700;}
#menu li a:hover {
font-weight:bold;}
#menu li ul li a:hover span{ color: #222222; }
#menu li ul {
margin:0px;
position:absolute;
left: 160px;
top:-90px;}
#menu li ul li {
padding:0px;
border:0px;
border-collapse:collapse;
margin:0px;
height:34px;}
#menu li ul li a{ margin:0px;padding:0px;border:0px;}
#menu li ul li a span{
display:block;
padding-top:7px;
font-weight:100;
line-height:1em;
font-size: 83%;}

This is some simple CSS that will make the UL/LI lists to really act like lists. Now the only issue is that you need it to act like a list. So the final piece of code to this puzzle is to add some JavaScript. I am using the jQuery library as my choice for creating this script, so it’s necessary to have that package (1.3+) installed for this to work. You can drop this script into the footer element inside of ‘script’ tags so it will run. It will run automatically on page load.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$(document).ready(function() {
/* Setup the Menu */
$('#menu > li > ul').hide();
$('#menu li.nav').hover(
/* on mouseover */
function(e) {
hoverMenu = this;
if(this == closingMenu) {
clearTimeout(closeMenu);
clearTimeout(openMenu);
$(this).find('ul:first').show('fast');
} else {
var newMenuOpen = function() {
$(hoverMenu).siblings('.nav').find('ul:first').hide();
$(hoverMenu).find('ul:first').show('fast');
}
openMenu = setTimeout(newMenuOpen, 500);
}
},
/* on mouseout */
function(e) {
closingMenu = this;
var closeMenu = function() {
$(closingMenu).find('ul:first').fadeOut('fast');
}
closeMenu = setTimeout(closeMenu, 500);
}
);
});

The final product is quite a nice and simple dynamic menu that adds just the right touch of usability. Now, typically, I would never say that a menu with sub menus popping up everywhere is something of a usability menu system, it’s not. But sometimes, a nice menu like this is needed, especially if there is a lot of information and ‘drill downs’ that need to be accessed quickly. In any case, you can see my demo here. Leave some comments if you have any questions, and enjoy! You can also see a fully implemented version at Xcessorries Squared.