Creating a Smooth Image Menu with Jquery
I have always thought that imagemenu sliding effect is really cool and that it would be nice if it worked with jQuery. Introducing a Mootools image menu ported to Jquery. If you have ever seen the image menu javascript for mootools by phatfusion and liked what you saw well here is a Sliding Image Menu alternative I've come up with using the power of jquery javascript.
Functionality Checklist for our Sliding Image Menu for Jquery.
Here is what we need our Jquery horizontal sliding image menu to do:
- Jquery compatible script.
- Mootools like sliding effect.
- Valid XHTML degrades well.
- Lightweight customizable script.
Let's take a look at the XHTML, CSS, and JavaScript that makes it all work.
Jquery Image Menu Version 1, View Demo, Download Source.

Here is the HTML for just the jquery Image Menu itself:
<div class="jimgMenu">
<ul>
<li class="landscapes"><a href="#">Landscapes</a></li>
<li class="people"><a href="#">People</a></li>
<li class="nature"><a href="#">Nature</a></li>
<li class="abstract"><a href="#">Abstract</a></li>
<li class="urban"><a href="#">Urban</a></li>
</ul>
</div>
Here is The CSS
.jimgMenu {
position: relative;
width: 670px;
height: 200px;
overflow: hidden;
margin: 25px 0px 0px;
}
.jimgMenu ul {
list-style: none;
margin: 0px;
display: block;
height: 200px;
width: 1340px;
}
.jimgMenu ul li {
float: left;
}
.jimgMenu ul li a {
text-indent: -1000px;
background:#FFFFFF none repeat scroll 0%;
border-right: 2px solid #fff;
cursor:pointer;
display:block;
overflow:hidden;
width:78px;
height: 200px;
}
.jimgMenu ul li.landscapes a {
background: url(images/landscapes.jpg) repeat scroll 0%;
}
.jimgMenu ul li.people a {
background: url(images/people.jpg) repeat scroll 0%;
}
.jimgMenu ul li.nature a {
background: url(images/nature.jpg) repeat scroll 0%;
}
.jimgMenu ul li.abstract a {
background: url(images/abstract.jpg) repeat scroll 0%;
}
.jimgMenu ul li.urban a {
background: url(images/urban.jpg) repeat scroll 0%;
min-width:310px;
}
The JavaScript
In the header section of your HTML file, you'll need to include jQuery and all the plug in files listed. The bare minimum setup look like this:
Finally include the jquery in your page or in an attached file.
This will activate our image menu, just remember we have css controlling most of the image menus style. You can customize the easing type and duration with the jquery easing plugin that we are using to achieve different slide effects.
Jquery Image Menu Version 2, View Demo, Download Source.
For this second version I have used kwicks to help with the ImageMenu animation. The advantage to using kwicks with our sliding image menu is the additional functionality that it brings in the form of sticky menu items which will stay open and custom events such as on click actions instead of hover.
The HTML remains the same for this version of jquery Image Menu except for the use of id instead of class.
<div class="jimgMenu">
<ul>
<li id="landscapes"><a href="#">Landscapes</a></li>
<li id="people"><a href="#">People</a></li>
<li id="nature"><a href="#">Nature</a></li>
<li id="abstract"><a href="#">Abstract</a></li>
<li id="urban"><a href="#">Urban</a></li>
</ul>
</div>
The CSS is adapted slightly for kwicks
.jimgMenu {
position:relative;
margin: 0px 0px 0px 50px;
padding: 0px;
width:475px;
height:200px;
overflow: hidden;
}
.jimgMenu ul {
list-style: none;
margin: 0px;
padding: 0px;
display: block;
height: 200px;
position: relative;
}
.jimgMenu ul li {
width: 95px;
float: left;
display: block;
overflow: hidden;
}
.jimgMenu ul li a {
text-indent: -1000px;
background:#fff repeat scroll 0%;
border-right: 2px solid #fff;
cursor:pointer;
display:block;
overflow: hidden;
height: 200px;
}
.jimgMenu ul li#landscapes a {
background: url(images/landscapes.jpg) repeat scroll 0%;
}
.jimgMenu ul li#people a {
background: url(images/people.jpg) repeat scroll 0%;
}
.jimgMenu ul li#nature a {
background: url(images/nature.jpg) repeat scroll 0%;
}
.jimgMenu ul li#abstract a {
background: url(images/abstract.jpg) repeat scroll 0%;
}
.jimgMenu ul li#urban a {
background: url(images/urban.jpg) repeat scroll 0%;
border-right-style: none;
}
The JavaScript
In the header section of your HTML, you will need to include jQuery and all the files below. The bare minimum setup will look like this:
This will activate our jQuery Sliding Image Menu plug-in. The last step is to include the script in our page by placing this script in your html head or document body.
Enjoy an Image Menu sliding effect for Jquery.
Filed in Design Tips & Techniques and tagged design, html, javascript, jquery
















Good stuff thanks for the help.
Nice script, thanks sharing.
I just wonder if it possible to have an other item selected, displaying the current page ?
Aloha, Thanks
Not sure if I understand exactly what you want to do but you can Use Sticky and Custom Events.
For Example: sticky : true, to have an image stay open or you can add
event : 'click' to make the menu animate on click instead of hover.
The code for the second image menu version with sticky images and on click events instead of hover would look like,
$().ready(function() {
$('.jimgMenu ul').kwicks({max: 310, duration: 300, sticky: true, event: 'click', easing: 'easeOutQuad', complete: 'callback'});
});
Perfect, just what I was looking for thanks!
Thanks for the great tips. I've been wrestling with the original mootools imagemenu, and I was happy to see this jQuery solution as an alternative. But I'm running into some of the same problems with this one...
I find I can get everything to work as long as I stick to five images and keep the ref names the same (i.e. Landscapes, People, Nature, etc.), but as soon as I introduce a 6th -- or in my case, a 6th-7th-8th-9th -- image or reference the image(s) by a different name, everything breaks.
What I'm looking for: Nne (9) images to load, the far left image to be displayed onOpen, the images to slide on rollover and an on click action which calls a URL for each image. I've checked and re-checked spelling and syntax, but I'm lost.
Any thoughts?
Hi,
To include more images you have to add them to both the css file and to the page list of images. You will also need to adjust the css .jimgMenu width to match how may images are included and make sure that overflow : hidden is not hiding your included images. As long as you use the same id labels within the css and page it will be called.
I cant seem to duplicate your issue. A sample to look at might help but you are able to add more images through adjusting the css and in-page html.
Thanks, Dylan. I've tried that and so far come up empty, but I've worked and re-worked this page and its support files so much now that it's a mess.
I'll go back and start the page from scratch and post the URL of the work-in-progress if I continue to have probs.
Either way, I'll report back on my success/failure.
Baby steps, I guess...
I have my nine 99) images in place, a 1px right border separating them and the slides perform as they should. But I'm still wrestling with an issue where the jimgMenu div is pushing the images to the right 40px, and apparently I have a conflict with .js libraries because I can either get a LightWindow effect to work on a link in a div above the imagemenu OR the imagemenu works, but not both. And it appears to be affected not only by the order of the .css files but by the .js libraries themselves.
I'll post a URL, but can you really tell much without the .css files too? (Ah, yes, Firebug!)
Good to hear your making progress.
Yes javascript has to be called in the order it is written or else you wind up with undefined variables and functions. Jquery will always conflict with lightbox as it is Mootols based. As an alternative jquery thickbox works great and is actually faster than lightbox. Or you can add a jquery no conflict to the jquery call and script.
Example:
add var $j = jQuery.noConflict(); to top of script than replace all the $ symbols with $j
Long live Firebug :P
Well, "progress" is a relative term...
Please take a look at: where I am right now
The image menu works, but I still haven't been able to figure out the 40px "push" to the right. The min-width on the last image is what I'd like on the first image onOpen, but when I move the property up to the first image it throws things off even more. The HREFs work, but ideally I'd like to try a click-to-open/stick/2nd-click-to-gotoURL option. And of course there's the lightwindow conflict, as this page doesn't reflect any of the changes you suggested (I may try the no-conflict first, then take a look at thickbox if/when I ever get these other issues under control).
In a nut shell: Slides work. 40px shift to the right. Images don't "shuffle" to fill the space. Menu opens with last image open when I'd like it to open with the first image.
Closer, perhaps. Any less frustrated? Negatory!
Hi Bill,
Your most certainly are getting conflicts by calling scriptaculous and portotype / lightbox and jquery. I didnt realize you were referencing the first version of the script.
For the 40px margin you want to add
left : -40px;
position : relative;
to .jimgMenu ul
I would also change the width in your #imageMenu_jq to 100%
To have the firstimage open add width : 415px to first image .css but keep the min-width on last as well.
This works but the only problem is the script is only looking at the hover state. So all is well as long as the user actually hovers over the first open image but if the other images are hovered over before it will not collapse. This is one of the reasons I developed version 2 of the script with kwicks which has a 3rd animated state and enabled me to not reinvent the wheel so to speak.
OK, I got it working, thanks to your tips. Thanks!
Before I take a look at the second version of the script with kwicks and solve that sticky dilemma, I experimented with the jquery no conflict to avoid the lightwindow issue. But I made these changes to the page:
add var $j = jQuery.noConflict();
$j(document).ready(function () {
// find the elements to be eased and hook the hover event
$j('div.jimgMenu ul li a').hover(function() {
// if the element is currently being animated
if ($j(this).is(':animated')) {
$j(this).stop().animate({width: "415px"}, {duration: 450, easing:"easeOutQuad", complete: "callback"});
} else {
// ease in quickly
$j(this).stop().animate({width: "415px"}, {duration: 400, easing:"easeOutQuad", complete: "callback"});
}
}, function () {
// on hovering out, ease the element out
if ($j(this).is(':animated')) {
$j(this).stop().animate({width: "48px"}, {duration: 400, easing:"easeInOutQuad", complete: "callback"})
} else {
// ease out slowly
$j(this).stop(':animated').animate({width: "48px"}, {duration: 450, easing:"easeInOutQuad", complete: "callback"});
}
});
});
and it didn't work. So I did a find-and-replace in the jquery.js itself ($j for $ throughout) and it still didn't work. (Well, the conflict went away, but the imagemenu stopped working.)
Must be sloppy typing or ADD on my part, eh?
Well, here's the kwicks version:
tester
Looks great in Firefox; breaks in Safari.
Back to the drawing board in search of a fix and a combo of script #1';s ability to open with the first left-hand image displayed and script #2's ability to slide all of the images back equally.
Looks Great! I think if anything my examples above of a jquery image menu really point out how jQuery is css based. Whether it be a small custom written script or full on plug-in jquery output is based on the css you can throw at it.
If Safari is not agreeing I'd bet it's a simple css fix. Try searching for safai css issues and fixes. Many times mac compatibility requires a small css hack depending on the rest of your layout. Also I'd suggest valid xhtml strict. I've viewed this menu on an iphone and it looked just as good with valid xhtml strict. You could also serve up a page just for safari users. ;P
Your second attempt at jquery no conflict would have worked if I had been carefuller typing. I meant add as include. :P
Change:
add var $j = jQuery.noConflict();
To:
var $j = jQuery.noConflict();
Thanks for the clarification on that no conflict -- I made the change and it works like a charm on both pages!
But why, even the -50px cheat on that div to get the banners to align left in the first page throw things off for me in IE7, suggesting the cheat *isn't* needed for IE. @#$%^*!!
I guess I'm staring at either some browser-specific CSS or choosing which platform(s)/browser(s) to ignore.
Hi I see what your saying. The 50px margin comes from the margin setting.
.jimgMenu {
height:426px;
left:-50px;
margin:0 0 0 50px;
overflow:hidden;
padding:0;
position:relative;
width:801px;
}
Your left:-50px is not needed, simply change to:
.jimgMenu {
height:426px;
margin:0;
overflow:hidden;
padding:0;
position:relative;
width:801px;
}
Overall it seems like the trouble you ar having is with your css. When you view my example you will see the 50px margin is just for placement on the example page. If you toggle the css on and off with firebug this becomes very obvious. It is also very easy to set css for ie using an if ie conditional css statement. IE conditional CSS is a practical and common work around that gets placed in your pages head and look like:
<!--[if IE]> <style type="text/css">.jimgmenu {example:css;} </style> <![endif]-->
Just wish I could use firebug in Safari or IE to test some changes on-the-fly as I can with FF. :-(
First I'd like to say thank you for this jQuery version. The issue that I'm having is, of course, in IE6. On Menu v.1 the graphic assigned the min-width will default to the preview width of 78px after I have hovered out; leaving an ugly space to the right of "Urban."
Anyone find a work around for this issue? Please advise. Thank you.
You can try display:inline-block instead of block.
Hello adriang, I would first try inline-block in your style sheet as suggested. If that doesn't work take a look at any possible css in your current page that could be effecting the menu. Most likely a margin or padding element is throwing the block display alignment off.
Very nice script - thanks a lot!
Is there any way to address active and hover states for the menu?
Hi Rainer, thanks.
Yes I just uploaded an updated version #1 which will add a style-able class="active" on hover to each list item and remove it on mouse out. Take a look with firebug and you will see the class being added and removed to each element as you hover over them. This is done with Jquery's .addClass() .removeClass()
View Updated Demo
For the second version with kwicks simply add a class to each li list item with the same name as the id. Example:
<li class="landscapes" id="landscapes"><a href="#">Landscapes</a></li> this will allow kwicks to add an active class to each image menu item as you hover over it.
Hi, thanl you very much!
Just what I was looking for.
Perfect.
Hi Dylan, I took a look at your version 1 and it's good with one small exception. In order to get the active class included and removed on a quick mouse roll over you should put the .addClass and .removeClass call before stop().
Like so: .addClass("active").stop()
...nice, included and updated in the Demo. thanks for spotting and pointing that out.
Dylan, just wanted to thank you again for your help with this. V2 is working flawlessly now, due in no small part to your advice and guidance.
The use of kwicks is terrific. I haven't done much experimentation with sticky menus, but on-click events work just fine.
Hi Bill, Good to hear. You integrated the image menu very nicely into the site, well done.
This system works great on my computer but refuses to work when uploaded to host server: http://aercosystems.com/image-menu-2.html . Any thoughts?
Aloha Leo,
It would appear that the packed js files have become corrupted upon upload as they are throwing errors. Try to upload an unpacked and un-minified version of jquery, kwicks and easing to see if that is the problem.
Thanks! The third time was a charm.
Is there an option to select which image will be open when the page first loads?
My current code:
$().ready(function() {
$('.jimgMenu ul').kwicks({max: 310, duration: 1500, sticky: true, easing: 'easeOutBounce'});
});
Thanks for a great application!
Sorry. I found the option:
$().ready(function() {
$('.jimgMenu ul').kwicks({defaultKwick:2, max: 310, duration: 1500, sticky: true, easing:
'easeOutBounce'});
});
Oh, this is great... I was just about to ask how to address which kwick will be open. But... is there a way to even address a certain state of this kwick?
For example the actice one?
Hi Rainer, thanks.
Kwicks should be adding the class="active" to each pic as it is hovered over. From there you should be able to style the active class via css.
I'm not sure if you got my question wrong or I do not understand your reply correctly...
I would like to open the page with a certain kwick (for example "defaultKwick:2") and in a given state (i.e. active or hover or...). Is tehre a way to address a) which kwick to open and b) in which state it is shown?
Thank you very much in advance...
Using image menu vs 2
Works fine in Dreamweaver CS 4 in all respects when saved and viewed in browser it looks great. When i upload to server and go to link in browser one of the images will not show it is just a blank spot. The blank one is the 7 th image of 9 total. Also all of the images past the 5 th one do not have a white edge like 1-5 images.
Any thoughts?
Thanks
Well, I'm back again. I've enjoyed months of error-free performance, but now that changes have been made to the client's page which require six banners to the right of a left-hand sidebar in place of the previous full-width 9-image setup, I'm getting headaches from IE again.
Page displays and works fine in Firefox and Safari, but all flavors of IE render the slider images as invisible. In other words, they're not there at all.
I've kept the ref files the same, changing only the params regarding location, no. of images, width, etc., but I'm lost on what IE is barfing on.
???
Hi,
This is a fantastic scrip and many thanks for sharing..
Can this image menu be positioned vertically rather than as is horizontal? If so, which bit of code needs to be changed.
Many thanks
These are amazing! Thank you!
Is it possible that when user click the image, the image stays open? (hover should still works). What I have in mind is, when u hover on the image, kwicks perform normally. Upon clicking a specific image, the image stays open, and i will load something on the body, based on the image clicked? hope you didn't got confused. Thanks.
Hi,
I installed this on a WordPress MU-BuddyPress site.
It works perfectly on FireFox and Chrome, but on Internet Explorer it won't work.
Error: j( ---- ).livequery is not a function.
Any ideas? I haven't been able to fix it.
By the way the site I was talking about is
here
I solved the "not a function" error code.
Now I isolated to problem to kwicks-1.5.1.js
This works beautifully in FF and Chrome.
But it doesn't work at all on IE.
When I delete kwicks, there are no error codes, and when I return it, IE is giving me the error:
"object doesn't support this property or method"
Hmm...
looks like there's now way for the image to stay open when clicked? in http://www.phatfusion.net/imagemenu/ image stays open but hover still works when mouse-hovered on other images.
Found the solution!
For this to work in IE, you need to open Kiwicks-1.5.1 file...
Look for:
container=$(this);
And replace with this
var container=$(this);
Now it works in IE!
Thanks for sharing the ie fix.
In response to aolee you can implement the sticky function within kwicks as well as a click event to have them stay open like so...
$().ready(function() {
$('.jimgMenu ul').kwicks({
isVertical : true,
sticky : true,
event : 'click'
});
});
In response to Rob El-Hani the above example also shows the use a vertical setup option which will require the css to be adjusted as well.
I'm working in Dreamweaver CS4 (Mac) and need help inserting the Jquery Image Menu (version 2) into my document. I have the basic layout (without images) at http://pages.interlog.com/~pagewise/basiclayout.html
I'm currently using the Phatfusion version, and although it works fine in all Mac browsers and in IE 8, Firefox and Safari in WinXP, it breaks in IE 6/7. I'm at least able to center it in XP using conditional style sheets, but cannot edit it furthur; I know some css and js tweaks but not nearly enough.... I'm not a coder.
Here is the test page with images (using Phatfusion version): http://pages.interlog.com/~pagewise/carbonneon5.html
Any suggestions would be greatly appreciated.
hi Dylan,
sorry but your code doesn't work, it stays open when clicked but doesn't ease when hovered. Check out the original from mootools version. when u clicked on an image it will open, but when u try hovering the other images, it will move. http://www.phatfusion.net/imagemenu/
thanks
Hello,
I, too, was having a lot of problems getting this going how I wanted with Mootools. Within 15 minutes, I had this one pretty well laid out how I like it. One question, though - Can I make my first graphic sticky, use mouseover to scroll effects, and make onclick make the graphic that the user clicked on sticky?
Thanks,
Scott
I've tried to have this awesome menu system as a "main categories" menu, and to insert two level submenu inside the different parts. But I didn't manage to get it work: the second level of menu doesn't develop.
If somebody want to check and give advise, he or she is very welcome.
My test page is here.
Thanks for your work
Once switching the menu to be vertical, awkward spacing appears between the images when hovering.
Image height: 200px
The images below cover 50% (100px) (can't figure out how to change that) and the space is another 100px.
Anyone got any idea how to eliminate the spacing? All margins and padding are set to 0.
Cheers.
I set the menu to be vertical and now spacing shows between the images (about 100px) when they slide out to show the active image. (images A,B,C: B and C slide down, leaving a 100px gap between the bottom of A and the top of B)
Also I can't, for the life of me figure out how to adjust the size of the preview image (how much is covered).
Anyone got any ideas?
Cheers.
Just to settle my own curiosity please...
I used your image menu on a website and it worked 100% in Firefox, Opera and IE7. Than came IE8. It kept pushing my menu to the right & down. When one changed IE8 to compatable mode, it was fine again.
After days of very little sleep & a lot of stress I changed to another menu alltogether.
What was / is the bug between Image Menu & IE8??
Dear Scott
Did you ever resolve your issue. I'd like to do the same.
Many Thanks
luke
Dear Scott
Did you ever resolve your issue. I'd like to do the same.
Many Thanks
luke
Dear Scott
Did you ever resolve your issue. I'd like to do the same.
Many Thanks
luke
Has anyone had any success getting "sticky" to work in Internet Explorer?
I'm using Version 2, and have been able to get the items to work flawlessly in Safari and Firefox. But for IE, I can't seem to get "sticky" to work. I've tested in IE8 and IE 6 so far.
Thanks!
Andreah