A fly-out menu is defined as a dynamic menu that appears on the left or right side of a parent menu immediately next to the selected item. To create a fly-out menu with jQuery, we basically need an HTML structure to work with, some proper CSS styles and, of course, jQuery. More specifically, in this post I'm going to show you how to create this effect with the animate()
method. Let's start with the HTML structure first:
<ul id="navigation"> <li><a href="#">Home</a></li> <li class="subnav"><a href="#">Articles »</a> <ul> <li><a href="#">Article 1</a></li> <li><a href="#">Article 2</a></li> <li><a href="#">Article 3</a></li> </ul> </li> <li><a href="#">About</a></li> </ul>
As you can see, the item with class subnav
contains our fly-out menu. Now we can apply some CSS styles:
#navigation { width: 15em; margin: 0; padding: 0.5em; background: #000; list-style: none; position: relative; } #navigation > li { padding: 0.3em; height: 100%; margin-bottom: 0.5em; background: #666; } #navigation > li > a { color: #fff; font: 1.5em "Arial Black", Arial, sans-serif; text-decoration: none; text-transform: uppercase; letter-spacing: 0.1em; height: 100%; display: block; } #navigation > li > a:hover {color: #ccc;} #navigation li ul { width: 0px; background: gray; margin: 0; padding: 25px 0.5em 0.5em 0.5em; list-style: none; position: absolute; left: -1000em; overflow: hidden; } #navigation li ul li { width: 90%; margin: 0 auto 0.5em auto; } #navigation li ul li a { display: block; height: 100%; padding: 0.3em; background: #ccc; color: #333; font: bold 1em Arial, sans-serif; text-decoration: none; } #navigation li ul li a:hover { background: #eee; } a.close { width: 20px; height: 20px; position: absolute; top: 3px; left: 50%; margin-left: -10px; display: block; background: #000; color: #fff; text-decoration: none; font: 1.4em Arial, sans-serif; line-height: 20px; text-align: center; }
Some things to note here:
- since we want only the direct children items to be styled in a certain way, we use the CSS child selector
- the fly-out menu has been hidden using negative absolute positioning; this helps us to keep our menu accessible
- we're going to add a closing button to the fly-out menu; this button will have the CSS class
close
.
Using display: none
is not a good thing, because screen readers interpret it as speak: none
and so they won't read the contents of our fly-out menu. Note also that we're going to use absolute positioning to position our fly-out menu exactly near the item it belongs to. Now jQuery:
$(document).ready(function() { $('<a class="close"/>').attr('href', '#').text('X').appendTo('#navigation li.subnav ul'); $('#navigation li.subnav > a:first-child').mouseover(function() { var $a = $(this); var navWidth = $('#navigation').outerWidth(); var itemTop = $a.parent().position().top; $a.next().animate({ top: itemTop, left: navWidth }, 200, function() { $(this).animate({width: '15em'}, 200); } ); }); $('#navigation li.subnav ul a.close').click(function(e) { $(this).parent().animate({ width: 0 }, 200, function() {$(this).animate({left: '-1000em'}, 200);}); e.preventDefault(); }); });
First, we append our closing button to our fly-out menu. Then, when a user moves his/her mouse over the active link, we animate our fly-out menu by absolutely positioning it using the top offset of the active item and the width of the parent menu as coordinates. Finally, we make it expand by changing its width. Conversely, when a user clicks on the closing button, our fly-out menu will contract and get back to its original position. You can see a demo below.