CSS-Tricks PSD to HTML

Garage Door Style Menu (using Animated Background Images with jQuery)

Right out of the box, jQuery provides the animate function, which allows us to morph some CSS attributes over time. Things like opacity, font-size, width, length, and position are all supported. There are a couple of notable limitations to this function though, and one of those is “background-position”.

Thankfully, there is a plugin to help with this, the Background-Position Animation Plugin by Alexander Farkas. (direct link to JS). With this, we can do some fun stuff!

We are going to build a “Garage Door” style menu, where an image “slides up” to reveal another image behind it.

View Demo Download Files

1. Creating the image needed

We are going to need three different types of images here. First is a background image for the entire menu itself. This is going to be one big image for the entire menu which will be the imagery which is “revealed” when the door opens. Check out my Photoshop file:

Notice my guides. I have these set up as a visual reference to what the “viewable area” is going to be within the garage frame. Note that the Photoshop files are included in the download for your reference.

Second, we’ll need to create the garage doors which we will call the “shutters”. These need to be separate graphics as each one will need to be animated separately. I made a separate template for this, so I could again use guides to keep things as close to centered and nicely spaced as possible.

Lastly, we need a window which will act as the garage frame. This is the nice touch that really ties the whole idea together. Since this is going to be the top-most layer, we will apply this to the anchor links themselves, so that they can be clickable with unique URLs.

2. Writing the HTML markup

Of coure, no matter how fancy we want to get with our menus, the markup should be clean and semantic so that with CSS and/or JavaScript disabled, the menu still looks and behaves like a menu.

Here is the menu markup:

<ul id="menuback">
	<li class="shutter" id="shutter1"><a class="link" href="#1">Link 1</a></li>
	<li class="shutter" id="shutter2"><a class="link" href="#2">Link 2</a></li>
	<li class="shutter" id="shutter3"><a class="link" href="#3">Link 3</a></li>
	<li class="shutter" id="shutter4"><a class="link" href="#4">Link 4</a></li>
</ul>

We have classes and ID’s applied all over, as we will need those hooks to do the styling and behaviors we want. But with CSS turned off, we have a very functional menu still:

3. The CSS

Here I’ll show you the whole CSS file, and then point out a few things below:

* 				{ margin:0px; padding:0px; }
body				{ background:#c1c1c1; }
a 				{ outline-style: none; }

ul#menuback {
	margin: 50px auto;
	list-style: none;
	background: url(../images/menu-bg.jpg);
	width: 800px;
	overflow: auto;
}

ul#menuback li.shutter {
	width: 200px;
	height: 100px;
	display: block;
	float: left;
}

ul#menuback li#shutter1 {
	background: url(../images/shutter-africanplains.jpg) no-repeat;
}
ul#menuback li#shutter2 {
	background: url(../images/shutter-reptiles.jpg) no-repeat;
}
ul#menuback li#shutter3 {
	background: url(../images/shutter-aviary.jpg) no-repeat;
}
ul#menuback li#shutter4 {
	background: url(../images/shutter-arcticzone.jpg) no-repeat;
}

a.link {
   width: 200px;
   height: 100px;
   display: block;
   background: url(../images/window.png) no-repeat bottom center;
   text-indent: -9999px;
}

We use the hard star-selector reset for cross-browser consistency. This is especially important in this example as differences in the margin and padding values for lists are common across different browsers.

The menu background is applied to the UL itself. Then each list item is set to a specific width and height (that of our window) and floated to the left (for a horizontal menu). The ID values on the LI items are used to apply the separate background graphics only. The anchor links, as I mentioned above, will be the top-most layer and thus use the window overlay. These will need to be set as a block level element, have with and height applied, and use text-indent to kick the text off the page.

4. The jQuery JavaScript

First things first, we include the latest version of jQuery on our page, as well as the plugin I linked to at the top of this article. Then we can write the jQuery JavaScript needed to make the garage door effect happen.

<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="js/jquery.backgroundPosition.js"></script>

<script type="text/javascript">
	$(document).ready(function() {

		//Set css in Firefox (Required to use the backgroundPosition js)
		$('#shutter1').css({backgroundPosition: '0px 0px'});

		//Animate the shutter
		$(".link").hover(function(){
		      $(this).parent().animate({backgroundPosition: '(0px -100px)'}, 500 );
		    }, function() {
		      $(this).parent().animate({backgroundPosition: '(0px 0px)'}, 500 );
		});
	 });
</script>

The first statement above is to account for a Firefox quirk actually. Just need to reset that background-position to 0px 0px.

Then we bind the “hover” event to each page element with the class of “link”. Remember we applied that class to each anchor link in the markup. We could have just used “a” as the target here, but that is dangerous as it is likely there will be more anchor links on any page this is actually used, so better to target a specific class. So when the hover event occurs over a page element with a class of “link”, jQuery finds the parent element, and does the background-position animation on that element. In our case, the LI element, with the unique shutters. Using the call-back function of the hover event (e.g. when the mouse leaves the area) we can animate the shutter back into position.

And there we have it, a nice looking menu with a pretty neat animated effect!

View Demo Download Files

 

Special Thanks

Special thanks to Toby Pitman for the orginal concept for this idea. Toby helped out another reader having a problem with background image animation on this thread. The basis for this example is from the example he posted there.


Theoretically Related Articles:


Responses


  1. 1

    Gravatar

    This is very cool, I will definitely need to keep this and use it somewhere!


    Comment by Shannon Snow — July 21, 2008 @ 7:39 am

  2. 2

    Gravatar

    Oops! On IE7 only works the first door!


    Comment by Josep Viciana — July 21, 2008 @ 7:43 am

  3. 3

    Gravatar

    Really nice effect, but Josep Viciana is right in IE only the first door works.


    Comment by mal — July 21, 2008 @ 7:52 am

  4. 4

    Gravatar

    Yup, extremely cool, but as others have said IE7 barfs on anything other than the first door.

    Line 23, char 16, ‘undefined’ is null or not an object (happens when you hover over the second or subsequent doors)

    It is obviously scared of the snake :-)


    Comment by Faris Raouf — July 21, 2008 @ 7:56 am

  5. 5

    Gravatar

    Extremely cool effect, but like Josep says it has flaw.. it also only shows ‘what’s behind door # 1′ in FF2


    Comment by Remkus — July 21, 2008 @ 8:06 am

  6. 6

    Gravatar

    Only opens the first door in FF2 and MSIE7 on XP Pro SP3.


    Comment by OrganizedFellow — July 21, 2008 @ 8:30 am

  7. 7

    Gravatar

    Funny behavior in FF3. The “Link1″ “Link2″ etc. text links still show up and the doors only open when you hover over the text links not the entire block?


    Comment by dangdang — July 21, 2008 @ 8:35 am

  8. 8

    Gravatar

    This problem in IE 7 and FF2 should be fixed.


    Comment by Chris Coyier — July 21, 2008 @ 8:40 am

  9. 9

    Gravatar

    Yep! Works great now on XP-SP3 FF3! This is awesome! I will be using it soon. Thanks!


    Comment by dangdang — July 21, 2008 @ 8:46 am

  10. 10

    Gravatar

    Hey Chris, did you get dugg (digg’d)? Been over half an hour trying to read this article. Glad I finally made it.


    Comment by Karl — July 21, 2008 @ 9:50 am

  11. 11

    Gravatar

    I move my mouse over and out of the pictures 5 times, and they still animates although i’ve move my mouse out :D


    Comment by htl — July 21, 2008 @ 10:44 am

  12. 12

    Gravatar

    yeah, there seems to be a bug .. you didn’t ignore the mouse event if you are already in the process of opening/closing the garage door.

    Just move your mouse over the door 10 times very quickly and then move it out….


    Comment by anonymous — July 21, 2008 @ 1:04 pm

  13. 13

    Gravatar

    Can’t see what all the fuss is about. It is a great bit of coding, and it works absolutely fine in Firefox 3.0.1, Opera 9.27, Safari for Windows 3.1.2 (525.21). Maxthon 2.1, and IE7 7.6.6006.18000 all on Windows Vista.


    Comment by Gordon — July 21, 2008 @ 2:09 pm

  14. 14

    Gravatar

    this was a css ah-ha moment, thanks.


    Comment by yuki — July 21, 2008 @ 4:17 pm

  15. 15

    Gravatar

    cool technique, working fine in mozilla


    Comment by Grafiko — July 21, 2008 @ 5:17 pm

  16. 16

    Gravatar

    bellissimo


    Comment by Digitalbrit — July 21, 2008 @ 11:08 pm

  17. 17

    Gravatar

    Cool stuff!!!
    Small enhancement: you could stop the animation when the mouse leaves, if it is still active.


    Comment by thomas peklak — July 22, 2008 @ 4:05 am

  18. 18

    Gravatar

    You are one of my favorite!

    This is the coolest menu I’ve ever seen in my short life. I have been looking for a menu in which the hover image moves with the mouse when navigate through the menu. Have you seen that one?


    Comment by Phe Le — July 22, 2008 @ 7:29 am

  19. 19

    Gravatar

    Chris, I would suggest putting .stop() in there like:

    $(this).parent().stop().animate(


    Comment by Benjamin Sterling — July 22, 2008 @ 11:55 am

  20. 20

    Gravatar

    @Benjamin: Ah ha, very nice. The live example has been updated and it works much nicer now. Helpful suggestions are always nicer than cries of “it’s broken!” =)


    Comment by Chris Coyier — July 22, 2008 @ 5:58 pm

  21. 21

    Gravatar

    What an awesome tutorial. This is my first time responding to a tutorial. I was impressed. Then again, I’ve been really impressed with jquery lately. Great tutorial. I’ve subscribed.

    Thanks,

    Jarod


    Comment by Jarod — July 22, 2008 @ 6:57 pm

  22. 22

    Gravatar

    Nice Job Chris!!

    You finally got me to say: nice, I have been waiting for one of yours to impress! Great work, nice effect, well planned, well documented, from one designer/developer to another.. pat yourself on the back.. best one yet! Keep them coming, I only hope to follow your lead and actually start using my blog.

    Nice comments box too! Glad I finally used it!


    Comment by Mike — July 22, 2008 @ 7:09 pm

  23. 23

    Gravatar

    Really nice effect! I love JQuery, so simple to get something which looks as good as something done in flash


    Comment by Matthew 'Web Design' Adams — July 23, 2008 @ 3:51 am

  24. 24

    Gravatar

    I really love the menu.
    In my debugging install of IE6 all that is seen is light blue background color rounded corner boxes (perhaps because they are png images). And on mouseover a quick flash of the background, probably a hover glitch?
    Great technique, and as a plugin with the bugs worked out would be just killer.


    Comment by ty — July 23, 2008 @ 8:15 am

  25. 25

    Gravatar

    Sick and slick. Nice work once again.


    Comment by Joe McCann — July 23, 2008 @ 1:45 pm

  26. 26

    Gravatar

    Chris, If you can working in the bounce effect, that would really make it pop.


    Comment by Benjamin Sterling — July 23, 2008 @ 8:11 pm

  27. 27

    Gravatar

    I hate to quote you here, but….didn’t I request an ass shot?


    Comment by David Walsh — July 25, 2008 @ 2:22 pm

  28. 28

    Gravatar

    great stuff!!, cross browser also :D


    Comment by Yussi ariefiyono — July 31, 2008 @ 4:06 am

  29. 29

    Gravatar

    Very ingenious. Would you create vertical one?


    Comment by Skracanie linków — August 3, 2008 @ 4:04 am

  30. 30

    Gravatar

    Thanks for this Chris, it will be incorporated into my blog re-design as a way to show off my latest work.

    Thanks again!


    Comment by Graeme — August 5, 2008 @ 4:19 pm


Leave a comment

Sick of typing in all this info everytime you comment? Register or Login and save yourself time!

Live Comment Preview


Thank you for visiting CSS-Tricks! I'm glad you found an article useful enough to print out! Remember to visit css-tricks.com often for more fresh content.