Beautiful Background Image Navigation with jQuery

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 […]

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.

Message from TestkingIf want to learn professional web designing but have no time to attent regular class then testking a+ is best solution though. Download the testking mcse design tutorials and testking VCP-410 study guide to learn how to create beautiful and unique logo designs.

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

Fresh news, inspo, code demos, and UI animations—zero fluff, all quality. Make your Mondays and Thursdays creative!

Feedback 335

Comments are closed.
  1. For some reason after the page is loaded when moving the mouse over the menus there is a pretty severe delay and it is a little jumpy. Any ideas?

  2. Hi

    Lovely plugin. But it does not seem to reload again in Drupal after the initial page load. Not sure why this is. Any ideas. I have used your css and html, so I am guessing its the jquery code.

  3. Hi,

    I’m trying to use this tutorial to accommodate 5 images instead of 3. Could anyone please explain the javascript/css/html logic or perhaps re-upload R.Bird’s archive?

    Thanks in advanced!

  4. very great!
    has anyone a idea, how to manipulate this script, that ist running like a slideshow in rotation ?
    could anyone upload the 4 piece variation, the link from r-bird is dead.
    Thanks

  5. Great design. Is it possible to have a different image for each block, but when hovering over it, the image expands and fills out to all blocks?

  6. Hi Mary! This menu is great! but I keep running into the trouble that it will work for a little bit, and then all fo the sudden the tiling will stop working and I dont know why…. I have not run into anything that I am changing specifically that would cause it to happen so I dont know what is going on, I am not sure if you can help or not, but either way your menu is great!

  7. thx to r.bird to reup the 4 pieces script.
    anyone knows how i can hide at start the first submenu ?

  8. Mary, you know a possibility the the submenü is hide and only mouseover it will show, mousout also hide the submenu ? thx for this great script !

  9. Hello,

    I am fond of your designs and work….

    I just want to know, if we can add some more sections in this layout. for e.g.: bg1, bg2,bg3,bg4,bg5.
    If yes, then can you help me how can it be possible.

    Thanks for your help.

  10. When I highlight over the “contact” button and then click on it, it defaults back to main page, with the 1st image and blue background.

    I would like to click on the contact page, with the 3rd image and yellow background to stay as is. How do I go about doing this?

  11. Apparently, I did not read all the comments because this question (the one above) has already been answered. My bad…

    Thank you for the great design Mary Lou.

  12. im so confused. when i upload it, it doesnt look anything like its supposed to. Help! ):

  13. Your website is fantastic. I am a newbie and would like to know if you can give me some suggestions for your tutorials to work correctly with Drupal

  14. Hi all.. great script! I have a question: How i can set like default the script without anything bg? (bg1-2-3), so i will see only the three link then on nouse hover there is the effect?Peace see u

  15. Great post as usual. Question. What are you using for your commenting? Is this a plugin? Very cool look.

  16. Mary Lou, I really like this tutorial. I am trying to figure out how make it fill the entire browser instead of having the background. Please help me. Thank you.

  17. thx for this share. i add this plugin in my website, but my screen is black if i start my site in internet browser.

    in dreamweaver it is looking normal and in internet browser is black rectangle.

    can u help me? what i am doing wrong

  18. Hi, Mary,

    Thanks so much for such a great navigation effect!!! I really love it!! Can you tell me how to substract a panel and make it to TWO panels only?? Really need your help!

  19. @ Lee Tempest; Are you happy to share how you managed your Joomla! integration? Be appreciated.

  20. Hi,
    Your guides are quite easy for me to follow. jQuerry’s still best technique.
    Thank for your great work

    Jimmy

  21. All I can say is thank you most sincerely for making my life so much easier today.

  22. not working for me on wordpress. i just try the quantum slution but cant make it work. anyone has the modified code?

  23. Hi Mary Lou,

    thanks so much for this! Great plug-in, very unique.
    I’d love to have this run automatically as some kind of slide show. Would that be difficult to achieve (I’m not so good with jQuery ;)). Thanks for your help!

    Nicole

  24. Hi Mary Lou,

    I love your post. I’m a rookie designer in Baltimore. Could you (or anyone) tell me how to scale this down to 498 pixels wide. Also, does anyone know if this will work inside one of Facebook’s new iframe pages?

    Craig

  25. This demo stopped working. So did the one I was using as a test. Did it call to an outside script which is no longer working or available? Help please. Thanks.

  26. For me it stopped workin’ too !!! Since today the slider is not working anymore. I used this file/script for a website I am developing together with the programmer. Now I am near to finishing, the javascript stopped working…HELP!

    Anyone knows how to fix this?

    • Hi Mars, for some reason the bgpos plugin is not working with jQuery 1.6. Please include a version lower than that. Cheers, ML

  27. i have modified an uploaded it as a website.

    http://melodys-lounge.de/

    a few hours later i couldn’t open it anymore.
    not online and offline also not. the java animation doesnt work i just see the first frame picture.

    help if you can 🙂

    thx

  28. b.t.w,
    if i download the original package it doesn’t animate anyway offline.

  29. Wowa, as I said in the previous comment: the bgpos plugin doesn’t seem to work with jQuery 1.6 and since we were pointing to the latest version, the whole thing stopped working. I’ve updated the zip file and now it should work. Hope it helps,
    ML

  30. Which of the files of the ones that we can download in the zip files are the ones that we need to update to make the animation work?

  31. i’ve seen your post to late, sry for that.
    now it works.
    perhaps you should store jquery.min.js
    lokal for future changes?!
    i’m new in this sry for mistake!

    great job this template btw !!!!!!!!!!!!!

  32. Hello,
    I’ve noticed that in ie, when you hover over the menu lists, all of the lines dissapear except for the one you stopped on. Does anybody else have this problem or it is just me?

  33. Hey Ken Pitts,
    you have to edit the index.html on the line with the javascript:
    Just change:

    with that:

    no files have to be updated except the index.html 🙂

  34. Hi Mary Lou, your work are fantastic!

    I used a several months ago your code a little bit transformed http://www.energodesign.rs.
    Look whats hapend, I discovered a week ago this site http://witech.jp :)) This guy completely copied site and also copy the google analitics code from our site :))

  35. Thank you Nikola! You site looks really great! Incredible that they just copied your site like that!
    ML

  36. Does this conflict with other jQuery image JS that is already part of the jQ package?

  37. ive a little problem , but i want to have it perfekt. im a newbe cause of that i cant solve it on my own.
    when i enter my site http://www.melodys-lounge.de/ the submenue grafik (red line on the bottom) doesnt start on the right place.
    and the “about button slides in the wrong direktion.

    i dont now if you support such questions. if not just ignore.

    like this work of you very much and hope i can learn from you!

    thx

    • Hi Wowa, when you look at the html where you have the “ul” with the class “sub1” then you can see that it has a wrong background-position. Currently it is
      background-position:-240 0px;
      and you should change it to
      background-position:0px 0px;
      It should work fine then! Hope it helps (can I get a free drink when I come and visit Neuwied??) 🙂
      Cheers and all the best,
      ML

  38. of course you can, you’re welcome!!! 😉

    thx for help.

    have you perhaps video tuts or have you thought about smth like that ? 🙂