In this article we'll see a simple comparison between CSS and jQuery menus. We're going to create two identical menus, one styled with CSS and another one animated with jQuery. The aim of this comparison is to help you to choose between the two solutions.
We have the following markup:
<ul id="nav"> <li><a href="#">Site</a> <ul> <li><a href="#">About</a></li> <li><a href="#">Projects</a></li> <li><a href="#">Contacts</a> <ul> <li><a href="#">Email Us</a></li> <li><a href="#">Social Networks</a></li> </ul> </li> </ul> </li> </ul>
We'll change only the ID of the main list to create our second structure. With CSS the code is as follows:
#nav { width: 12em; margin: 1em 0 6em 1em; padding: 0; list-style: none; font: 85% Arial, sans-serif; background: #000; height: 2em; } #nav ul { width: 100%; background: #000; } #nav > li { display: block; height: 100%; position: relative; } #nav a { display: block; padding: 0.4em; color: #fa0; text-decoration: none; } #nav a:hover { background: #333; color: #fff; } #nav > li > ul { position: absolute; top: 2em; display: none; } #nav > li > ul > li > ul { position: absolute; bottom: 0; left: 12em; display: none; } #nav li:hover > ul { display: block; }
What are the problems with the CSS solution? First of all, elements are shown immediately and without any transition effects. Secondarily, the selector chain may grow exponentially as you increase the nesting level.
jQuery, instead, requires much less styles:
#nav-2 { width: 12em; margin: 1em 0 1em 1em; padding: 0; list-style: none; font: 85% Arial, sans-serif; background: #000; height: 2em; } #nav-2 ul { width: 100%; background: #000; display: none; } #nav-2 li { display: block; height: 100%; position: relative; } #nav-2 a { display: block; padding: 0.4em; color: #fa0; text-decoration: none; } #nav-2 a:hover { background: #333; color: #fff; }
As you can see, CSS styles are much simpler. With jQuery we can control the level of nesting as well as the effects attached to the sublists:
var SlideMenuHandler = { levels: function($menu) { $('ul', $menu).each(function(i) { var level = i + 1; $(this).data('level', level); }); }, handle: function(menu) { $('a', menu).each(function() { var $a = $(this); var parent = $a.parent(); var next = $a.next(); if (next.is('ul')) { var level = next.data('level'); if (level > 1) { next.css({ position: 'absolute', bottom: 0, left: '12em' }); } parent.hover(function() { if (level > 1) { next.stop(true, true).show(400); } else { next.stop(true, true).slideDown(400); } }, function() { if (level > 1) { next.stop(true, true).hide(400); } else { next.stop(true, true).slideUp(400); } }); } }); }, init: function() { this.levels('#nav-2'); this.handle('#nav-2'); } }; SlideMenuHandler.init();
So what's the best solution? Everything depends on your needs: if you're managing simple menus, then CSS is the perfect solution. Instead, if you're handling complex menus (such as those in WordPress), then you should consider using jQuery.
You can see the demo below.