- Feb 24, 2009
- 62 Comments
- Tutorials
How to Make an Impressive Animated Landscape Header with jQuery
Content doesn’t always have to stay visible. Sometimes it can hide in the most unexpected locations.
In this tutorial we’ll start with a cartoon themed header, build two different states for content and animate a transition between them using jQuery.
This is going to be a big undertaking.
I’ll warn you now, there will be a lot of code to copy and paste. I will cover the essentials in the main tutorial, but in the interest of space I will not do a line by line analysis. If you’re in need of any additional help by the end, feel free to leave a question in the comments. Sound good? Let’s get going!
The Goal – Green Cartoon Hills
Before we start, let’s take a look at the end result. It’s a cartoon themed landscape with elements which slide out to reveal additional content. The screenshot below demonstrates the layout when fully expanded.

Step 1 – Get Your Files Organized
Just so we’re all on the same page throughout the tutorial, here’s a screenshot of my project file structure:

As you can see, you’ll need to make three main files for the CSS, jQuery, and XHTML respectively. We’re going to keep this as simple as possible on the file structure end.
You’ll also want to make a directory for Javascript plugins, and another for images. You can grab a ZIP file of the images used in this tutorial here.
For those interested, the RSS badge is from a tutorial on Photoshop Star, while the background starburst overlay comes from a great brush pack on myPSLink. The remaining images were drawn for this tutorial using the pen tool in Photoshop.
IE6 Disclaimer – Many of the project images above use the PNG format in order to have cleaner transparency. To keep things short, I will not be demonstrating the workaround for transparency errors in IE6. If this affects you, I recommend reading this article for a solution.
Step 2 – Bring on the Plugins
This project will make use of two different plugins along the way. You will need to download both and place them into the “js” folder under your project files.
The first is the jQuery Easing Plugin. As you’ll recall, it is responsible for making the motion in animations much smoother. In this case, for the sliding elements as they move in and out of sight.
The second is the jQuery Delay plugin by EvanBot. It allows for very easy to use time delays between functions. We’ll use it in this tutorial to coordinate and delay effects smoothly.
Step 3 – Build the Structure in XHTML
Here’s the HTML
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Animated Landscape Header with jQuery</title> <link rel="stylesheet" href="landscape-header.css"/> <script src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js" type="text/javascript"></script> <script src="js/jquery.easing.1.3.js" type="text/javascript"></script> <script src="js/jquery.delay.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" src="landscape-header.js"></script> </head> <body> <div id="wrapper"> <div id="header"> <img class="foreground" src="images/foreground-land.png" alt="Welcome to the City"/> <div id="titlebar"> <h1>Welcome</h1> </div> <div id="sliders"> <div class="village"> <div class="village-padding"> <h2>Hidden Heading</h2> <p>ac ultricies ante. ultricies egestas Pellentesque Aenean et Vestibulum fames quam vitae, amet, libero leo. morbi malesuada eleifend tempor turpis sit et amet tristique placerat feugiat tortor Mauris senectus eu mi habitant Donec quam, eget, semper. egestas. est. netus vitae sit </p> </div> </div> <div class="cloudbar"> <div class="cloud-padding"> <h2>Subscribe via RSS</h2> <a href="http://feeds2.feedburner.com/buildinternet"><img src="images/feed-icon.gif" alt="Subscribe today!"/></a> </div> </div> </div> </div> <div id="content"> <h2>But Wait!</h2> <p>You've got options! <a href="#" class="toggle">Toggle </a> between states.</p> </div> </div> </body> </html> |
Notice the order in which the jQuery files are being loaded. The framework library first, plugins second, and then our code last. Try to keep a similar order to avoid any conflicts. Make sure to load the CSS above the javascript!
The layout is pretty straightforward. The header contains the foreground hill image, the welcome text, and the sliding content divisions. The content area lies directly below the header, and does not have an impact on the top’s animation. In this tutorial, we’ll use it as a place to house the animation toggle switch.
Step 4 – Order and Style with CSS
Copy this code into your CSS file, and then meet me below for an explanation.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
@charset "utf-8"; /* CSS Document */ *{ border:none; } body{ background:#7cc5da; margin:0; padding:0; } #wrapper{ width:960px; margin:0 auto; height:800px; background:#3b902f; } #header{ height:500px; width:960px; background:url('images/sky-bg.jpg') no-repeat top left; position:relative; overflow:hidden; } #header .foreground{ position:absolute; top:350px; z-index:100; } #sliders{ overflow:hidden; } #sliders>*{ display:none; } #titlebar{ position:relative; z-index:0; top:100px; text-align:center; } #titlebar h1{ font-family:arial,sans-serif; color:#37626F; padding:10px; font-size:70px; letter-spacing:-2px; } .village{ position:absolute; top:366px; left:30px; z-index:90; height:500px; width:470px; background:url('images/village-background.png') no-repeat top center; } .village-padding{ padding:120px 25px 20px 25px; } .village-padding p{ color:#F7F7F7; font-family:"Lucida Grande",arial, sans-serif; font-size:13px; line-height:1.6em; } .village-padding h2{ color:#FFF; font-family:arial, sans-serif; font-size:26px; margin:0; padding:0; letter-spacing:-2px; } .cloudbar{ position:absolute; top:-465px; left:600px; z-index:90; height:325px; width:252px; background:url('images/cloud-bar.png') no-repeat bottom center; } .cloud-padding{ padding:20px; text-align:center; } .cloud-padding p{ color:#F7F7F7; font-family:"Lucida Grande",arial, sans-serif; font-size:13px; line-height:1.6em; } .cloud-padding h2{ margin:0px 0px 25px 0px; padding:0; color:#37626F; font-family:arial, sans-serif; font-size:26px; letter-spacing:-2px; } #content{ text-align:center; padding:10px; } #content h2{ color:#FFF; font-family:arial, sans-serif; font-size:26px; letter-spacing:-1px; } #content p{ color:#FFF; font-family:"Lucida Grande",arial, sans-serif; font-size:13px; } #content a{ color:#FFED2F; text-decoration:none; } |
Most of the styling above handles type and spacing, but there are a few important things to note:
- In order to move an element using the jQuery animate() function, its position type must first be changed. I have chosen to use “relative” in this example, because it is more flexible than absolute.
- The varying z-index values allow us to stack elements on top of each other. A high number stacks over a lower number. In this tutorial, the foreground landscape is the front layer. Since it is a PNG and has transparency, the layers behind it will remain visible around its curves.
- The sliding elements are set to display:none by default, and are made visible initially by the jQuery on ready. This give the page’s foreground time to load before showing the content behind it. Otherwise, the village column may be exposed before the foreground has time to cover it.
- The initial starting positions for the two content columns (.village and .cloudbar) keep them off the screen. The village buildings are the only part visible by default. The jQuery is responsible for moving them between states:

Step 5 – Animate the Transitions with jQuery
The jQuery below will take the pieces we’ve put in place and make them work together in harmony. A detailed breakdown follows the code.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// JavaScript Document $(document).ready(function(){ $buildingup = false; $("#sliders>*").show(); //Blurs all links when clicked $("a").click(function(){ $(this).blur(); }); $(this).delay(2000,function(){ $("#titlebar").fadeOut(1000); }); $(this).delay(3500,function(){ //Show the elements $(".village").stop().animate({top:'30px'}, {queue:false, duration:2000, easing: 'easeInOutBack'}); $(".cloudbar").stop().animate({top:'0px'}, {queue:false, duration:2000, easing: 'easeInOutBack'}); $buildingup = true; }); $("a.toggle").click(function(){ if ($buildingup == false){ $("#titlebar").fadeOut(1000); $(this).delay(1000,function(){ $(".village").stop().animate({top:'30px'}, {queue:false, duration:2000, easing: 'easeInOutBack'}); $(".cloudbar").stop().animate({top:'0px'}, {queue:false, duration:2000, easing: 'easeInOutBack'}); $buildingup = true; }); }else{ $(".village").stop().animate({top:'366px'}, {queue:false, duration:2000, easing: 'easeInOutBack'}); $(".cloudbar").stop().animate({top:'-465px'}, {queue:false, duration:2000, easing: 'easeInOutBack'}); $buildingup = false; $(this).delay(2000,function(){ $("#titlebar").fadeIn(1000); }); } }); }); |
Remember that this header will have two unique states:
- The first will display a welcome message in the center with the landscape below. The text while fade in and out.
- The second state will show a raised village column and a second column hovering on the right. Both will slide in and out using easing.
The delay plugin is used stop the animation from starting until 3.5 seconds after the page loads. This lets the viewer get their bearings, and read the welcome message before experiencing the transition.
The “buildingup” boolean keeps track of when the columns are being displayed (true) or are hidden behind the hills (false). An if statement triggered by the toggle link checks for the current state, and then proceeds to show or hide as needed.
Conclusion – Show us Yours!
As nice as the village landscape is, it is a very specific design and probably won’t translate directly to very many real world applications. The important elements are the use of z-indexes to stack layers, and jQuery to show and hide expanding content with animations.
This was a lot to cover, and I’m certainly liable to have missed something. Please don’t hesitate to tell me. Let me know what would help you understand this more, and I’d be happy to help.
If you end up building any great designs using these effects, be sure to share them in the comments. You have your challenge, now let’s see what creativity comes out of it.










