From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
In this tutorial we are going to create a beautiful navigation that has a background image slide effect. The main idea is to have three list items that contain the same background image but with a different position. The background image for each item will be animated to slide into place in different times, creating a really nice effect. The background image sliding direction from the list item in the middle will depend on which item the user was before: coming from the right, it will slide from the left and vice versa.
On top of that we will have sub-menus that appear with their semi-transparent background sliding in. These backgrounds create an awesome effect of actually just being one element that slides into place, changing its color.
Note: There is a new version which let’s you customize things better:
Sliding Background Image Menu with jQuery
We will be using the amazing Background-Position Animation Plugin by Alexander Farkas.
The photos that we will be using are from Pat’s beautiful B&W collection on Flickr.
There will be a little bit of CSS3 involved which absence will almost not be notable when using a browser that does not support its properties (like IE).
We tried to make this one cross-browser compatible and voilà! It works beautifully in Google Chrome, Firefox, Opera, Safari, IE8, IE7 and guess what, it even works respectively in IE6. (We are using an adapted style sheet and you will have to apply some PNG fix if you want the sub-menu backgrounds to be semi-transparent. )
OK, so let’s get started!
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The Markup
The HTML will consist of a wrapper div and an unordered list with three list items. We will initially set some “bg” classes that will have the respective background images. The “menuWrapper” will always have the “bg” class of the current list item so that we have the background image of the current list item.
<div id="menuWrapper" class="menuWrapper bg1"> <ul class="menu" id="menu"> <li class="bg1" style="background-position:0 0;"> <a id="bg1" href="#">Our Passion</a> <ul class="sub1" style="background-position:0 0;"> <li><a href="#">Submenu 1</a></li> <li><a href="#">Submenu 2</a></li> <li><a href="#">Submenu 3</a></li> </ul> </li> <li class="bg1" style="background-position:-266px 0px;"> <a id="bg2" href="#">Our Brands</a> <ul class="sub2" style="background-position:-266px 0;"> <li><a href="#">Submenu 1</a></li> <li><a href="#">Submenu 2</a></li> <li><a href="#">Submenu 3</a></li> </ul> </li> <li class="last bg1" style="background-position:-532px 0px;"> <a id="bg3" href="#">Contact</a> <ul class="sub3" style="background-position:-266px 0;"> <li><a href="#">Submenu 1</a></li> <li><a href="#">Submenu 2</a></li> <li><a href="#">Submenu 3</a></li> </ul> </li> </ul> </div>
For the background animation plugin to work correctly we need to set the position of the background image as inline styles initially. We already set the right position for each background image, for example, the third item will have the background image positioned to the outer right.
As you can see, every list item has another sub-list with three more items. The background image position of these sublists is set to a value that hides the image. When we animate the background then, we will create the effect of sliding it in from the left or the right.
The CSS
Let’s start by the general style of the the “menuWrapper” which will contain the font styles and the size of the whole element:
.menuWrapper{ font-family: "Trebuchet MS", Arial, sans-serif;; font-size: 15px; font-style: normal; font-weight: normal; text-transform:uppercase; letter-spacing: normal; line-height: 1.45em; position:relative; margin:20px auto; height:542px; width:797px; background-position:0 0; background-repeat:no-repeat; background-color:transparent; }
The list and the list items of the first layer will have the following style:
ul.menu{ list-style:none; width:797px; } ul.menu > li{ float:left; width:265px; height:542px; border-right:1px solid #777; background-repeat:no-repeat; background-color:transparent; } ul.menu > li.last{ border:none; }
The selector “>” addresses only the li elements of the first layer and will not be applied to the ones of the sub-menus. We will give the last li the class “last” in order to remove the right border.
The following three classes define the background images. We will give these classes to all the li elements depending on which one we hover. So, if we hover the second li, we will give the “bg2” class to all the first layer list items:
.bg1{ background-image: url(../images/1.jpg); } .bg2{ background-image: url(../images/2.jpg); } .bg3{ background-image: url(../images/3.jpg); }
Let’s define the look of the link elements in the first layer list. Since the li elements have a big height, we need to push the link elements down. We do that by setting a high top margin:
ul.menu > li > a{ float:left; width:265px; height:50px; margin-top:450px; text-align:center; line-height:50px; color:#ddd; background-color:#333; letter-spacing:1px; cursor:pointer; text-decoration:none; text-shadow:0px 0px 1px #fff; }
To center the text of a link element vertically, you can give a line-height value equal to the height of the element. (I don’t know why, but when I started with learning CSS, I automatically always used paddings to adapt the height of the element and to center it. Using line-height was a real delight because you can control sizes much better like that.)
The second layer lists would naturally appear after the first layer list, so we use a negative top margin to “pull” them up:
ul.menu > li ul{ list-style:none; float:left; margin-top:-180px; width:100%; height:110px; padding-top:20px; background-repeat:no-repeat; background-color:transparent; }
The li elements of the sub-menu will be initially hidden. In the script we will fade them in when we hover over their parent list item link:
ul.menu > li ul li{ display:none; }
Now we define the classes for the background images of the sub-menus:
ul.menu > li ul.sub1{ background-image:url(../images/bg1sub.png); } ul.menu > li ul.sub2{ background-image:url(../images/bg2sub.png); } ul.menu > li ul.sub3{ background-image:url(../images/bg3sub.png); }
The link elements of the li elements will have the following style:
ul.menu > li ul li a{ color:#fff; text-decoration:none; line-height:30px; margin-left:20px; text-shadow:1px 1px 1px #444; font-size:11px; } ul.menu > li ul li a:hover{ border-bottom:1px dotted #fff; }
The first sub-list will be shown in the beginning:
ul.menu > li ul.sub1 li{ display:block; }
And that’s all the style. Take a look at the ZIP file for the IE6 style sheet.
Now let’s take a look at the JavaScript.
The JavaScript
What we do in the script is the following: we first check where we are coming from and then we animate the background positions of the list elements in the first level and the backgrounds of the sub-menus accordingly:
$(function() { /* position of the <li> that is currently shown */ var current = 0; $('#bg1,#bg2,#bg3').mouseover(function(e){ var $this = $(this); /* if we hover the current one, then don't do anything */ if($this.parent().index() == current) return; /* item is bg1 or bg2 or bg3, depending where we are hovering */ var item = e.target.id; /* this is the sub menu overlay. Let's hide the current one if we hover the first <li> or if we come from the last one, then the overlay should move left -> right, otherwise right->left */ if(item == 'bg1' || current == 2) $('#menu .sub'+parseInt(current+1)) .stop() .animate({backgroundPosition:"(-266px 0)"},300,function(){ $(this).find('li').hide(); }); else $('#menu .sub'+parseInt(current+1)) .stop() .animate({backgroundPosition:"(266px 0)"},300,function(){ $(this).find('li').hide(); }); if(item == 'bg1' || current == 2){ /* if we hover the first <li> or if we come from the last one, then the images should move left -> right */ $('#menu > li') .animate({backgroundPosition:"(-800px 0)"},0) .removeClass('bg1 bg2 bg3') .addClass(item); move(1,item); } else{ /* if we hover the first <li> or if we come from the last one, then the images should move right -> left */ $('#menu > li') .animate({backgroundPosition:"(800px 0)"},0) .removeClass('bg1 bg2 bg3') .addClass(item); move(0,item); } /* We want that if we go from the first one to the last one (without hovering the middle one), or from the last one to the first one, the middle menu's overlay should also slide, either from left to right or right to left. */ if(current == 2 && item == 'bg1'){ $('#menu .sub'+parseInt(current)) .stop() .animate({backgroundPosition:"(-266px 0)"},300); } if(current == 0 && item == 'bg3'){ $('#menu .sub'+parseInt(current+2)) .stop() .animate({backgroundPosition:"(266px 0)"},300); } /* change the current element */ current = $this.parent().index(); /* let's make the overlay of the current one appear */ $('#menu .sub'+parseInt(current+1)) .stop().animate({backgroundPosition:"(0 0)"},300,function(){ $(this).find('li').fadeIn(); }); }); /* dir:1 - move left->right dir:0 - move right->left */ function move(dir,item){ if(dir){ $('#bg1').parent() .stop() .animate({backgroundPosition:"(0 0)"},200); $('#bg2').parent() .stop() .animate({backgroundPosition:"(-266px 0)"},300); $('#bg3').parent() .stop() .animate({backgroundPosition:"(-532px 0)"},400,function(){ $('#menuWrapper').removeClass('bg1 bg2 bg3') .addClass(item); }); } else{ $('#bg1').parent() .stop() .animate({backgroundPosition:"(0 0)"},400,function(){ $('#menuWrapper').removeClass('bg1 bg2 bg3') .addClass(item); }); $('#bg2').parent() .stop() .animate({backgroundPosition:"(-266px 0)"},300); $('#bg3').parent() .stop() .animate({backgroundPosition:"(-532px 0)"},200); } } });
And that’s it! A beautiful cross-browser capable effect!
I hope that you enjoyed the tutorial.
Your code and design are very nice!
I am having a little issue, when I use it on my site its not showing up at all, even though the code and links to everything are correct.
Any help would be much appreciated! 🙂
Dumb question, but where do I go in the code to change the light yellow background? All bg attributes I see in css + html are “transparent”
Mary Lou This is great. Thanks for listing the code. I got to go through it and see if I can figure it out!
Sorry- found it. Not enough coffee
jQuery and beauty go hand in hand 🙂
Thanks for the code-share!
It just magically!
Hi MARY LOU,
Wonderful work. hoping someone gives us the info for implantation in WordPress and Joomla. Looking forward to using this on my WP portfolio site soon.
Thanks, You rock.
DG.
I have managed to make it work with WordPress, but it is moved some 40px to the right. How can I fix that?
great slider btw
Thanks for great work, neat, clean, I love it.
Best
Just perfect.
Thanks for this job.
All your jQuery navigations are awesome! I like them very much!
Thanks a lot in going for and providing details as how to go about using JQuery to provide navigation and backgrounds images. A great posting keep sharing stuff like this….
love this! really beautiful effects.
Hi,
I really like your usefull effect. I need to use it now and I still have a little problem.
in a submenu link (see here below) I tried to use a href for a mailto action.
I tried it with a clear e-mail address before using a merged string (a splitted e-mail address in many part before merging it in the variable $pourmoi). Then I used the given submenu line composed for this action in PHP like this :
echo ” E-Mail“;
Even with a clear written e-mail address like this it does not fill in the mail but href well to an empty mail :
echo ” E-Mail“;
Could you please tell me how to get it work as a link for a href mailto action ?
Sincerely thanks and have a nice day,
Miguipda 😉
Oups it wrote it as a link in my previous comment. Here is the concerned code :
the brackets have been symbolically replaced by … to prevent the effect done in the previous comment :
echo ” …li…a… target=’_blank’ href=’mailto:’bidoo@gmail.com’?subject=[Request] From Website – Contact&body=Bonjour,%0AHi,%0A\u60A8\u597D,%0A’ target=’_blank’…E-Mail…/a…/li…”;
Hi,
another little problem. Have a look.
If I use this URL the hover menu display perfectly the submenus :
http://test.watercolors-gallery.eu/
But if you choose another language at the top right all then menu does not answer to the mouse over :
http://test.watercolors-gallery.eu/index.php?lang=en
How to solve it ?
Sincerely thanks and have a nice day,
Miguipda 😉
Hi,
ok the language parameter problem was due to a css conflict with some of mine css.
Sorry for disturbing. Then you may delete my previous comment.
But there is still a problem when I try to use a submenu link to use it as a href mailto (by giving it the e-mail address, the subject and the body).
How to solve it ?
Sincerely thanks and have a nice day,
Miguipda 😉
Hi,
for the e-mail link problem I had I found a solution without being able to understand why I got this problem at the beginning of use.
Then sincerely thanks for this great web tool. I really appreciate it and it gives beautifull style for the webpage I made.
Thanks a lot and have a nice day,
Miguipda 😉
Dear Mary Lou and others,
thanks for your really functional tool I used to show paintings of my wife to all our friends.
To be able to finish the website could you please tell me which line must be adapted to tell the menu to start showing the second or the third menu when the page is loaded.
By example I want this page start on the second menu item : http://test.watercolors-gallery.eu/social.php?lang=fr
Must I just change the javascript line : var current = 0; ?
By just setting it to 1 or 2 following I want to set it starting with the second or third menu item or must change something else ?
Sincerely thanks and have a nice day,
Miguipda 😉
Any ideea how to add another submenu? Either to the right of the curent one or to the left. Needs to fallow the same backround and fonts as the normal submenu. Thanks!
hi,
can someone tell me how can i make this code with 6 – 7 column ?