responsove banner02

Ok, it’s time to finish off this banner with some animations provided by some JavaScript, and some styling, courtesy of some CSS code. To view a demo of what we're creating in this post, visit this page. Before I continue, please make sure that you have read the previous blog post which set up all the foundations of how this banner works. If you’ve read that, and understood it, lets pop your hard-hat back on, and get to work.

Story so far

In the previous blog I left you with an HTML structure which consisted of an unordered list containing some list items. These list items in turn contained some anchor tags, along with all the elements needed to populate the banner slide. I also left you with the first function of the JavaScript file, showcaseBanner, which started adding classes and click events to the previous and next buttons.

Putting the hard-hat back on

So here we go. We first of all need to make some additions to the HTML structure. On the Daymedia site, although the banner is responsive and will work on mobile devices, the banner was also created with a max width in mind. So in your HTML surround your banner slider element (<div class="banner-slider">) with the following:


<article class="container">
	<div class="side-padding">

		<div class="banner-slider">
		<!-- ... banner stuff ... -->
		</div>

	</div>
</article>

Download the CSS code from here and include it into your html file. This should start to make things look a lot more polished, even without the animations being made. You should now see that both of the banners are on the page, one above the other. If you resize the browser window, you will see how both of the banners work responsively. When I approach responsive design at Daymedia, I use the Mobile First pattern. If you’re unsure of what that is, please give this article a read. It’s well worth understanding this concept, and it will help you structure your designs on the web for every screen size. Likewise if you’ve not come across media queries before, take a look at this article to learn how they’re used. I’m not going to go into depth on the CSS, as this blog is more about the animations, but I will highlight things I feel are important.

The banner area

You don’t want the elements that are inside the banner, appearing outside the banner when they animate, so the overflow of the banner area is set to hidden. The position is also set to relative, so that we can manipulate each slide.

All Slides

Before you added the CSS file to your page, each slide was positioned one above the other. This is because they’re in a list, and rightfully so, but obviously that's not quite the look we’re going for. So to get all the slides layered on top of one another, each banner is set to have a position of absolute and a top value of 0. In order for animations to work later on, we need to absolutely position the elements within the slides, so the slides have to be position:relative.

Individual Slides

The idea here is to position all the elements in your CSS in the places they will be when they are static. In other words, the place that all the elements will stop after they have animated into the banner.

Ground Rules

There are a couple of ground rules that you need to follow in your CSS:

  • For any element you want to animate, you need to make sure that it is absolutely positioned, otherwise the JavaScript later on will not work.
  • If you want to animate something in and out of the edge of the banner, it’s absolute position needs to be 0, based on the side it’s animating from and to. So for example, I have an element that will fly in and out on the right side of the banner, the element must have a right position of 0. If it’s animations were to be in and out of the left side, it would need to have, left:0. You can then use padding to move the element across the banner to the position you want it.

The Animations

Right, here’s where the fun starts. The animations are what bring the banner to life, and you can create as many animation as you like. The animations you will find in this tutorial have been written by me using jQuery. It’s easier than you think! Do you remember from the last blog there was a function I told you about, but we didn’t write it? Well, now is the time. Create a function called bannerSwitch which accepts 2 arguments.

  • target_element - This is the banner list element
  • backwards - This sets whether the list should go forward or backwards

You can get the code for it here.

Explaining The Code

So first of all, we need to search for any currently displayed banners, and if there aren’t any, then we will set the current banner to the last in the list.

// Find the currently displayed banner
var $active = $(targetElement + ' li.active');

// Set the currently displayed banner if it is empty
if ($active.length == 0) $active = $(targetElement + ' li:last');

The reason we’re setting the element to the last in the list, is because it’s very likely that if one isn’t already selected, it’s going to be the first time this has been run, so we want the first banner to animate into view. Now we check to see if the banner should be travelling forward or backwards, and then get the correct previous/next banner in the list.

// Find the next banner to be faded in
if(backwards)
	var $next = $active.prev().length ? $active.prev() : $(targetElement + ' li:last');
else
	var $next = $active.next().length ? $active.next() : $(targetElement + ' li:first');

Next we set up all of the different types of animations we want to use. They are grouped these into ‘animate in’ and ‘animate out’, but these can be split off into separate functions if you like. For simplicity, I’m not doing that in this tutorial. The jQuery animate function gives you a lot of control over how you want your animations to look. You can do something simple, like fade in and out, to something complicated like drawing a path around the screen for an element to animate along. If you want to learn how to fully use jQuery animate, then this is a good place to start. The first animation we’ll set up will be for the background image that exists on the next banner.

//Background in and make the next banner visible
$next_background = $next.find('.background');
$next.css({display: 'block'});
$next.addClass('active');
$next_background.animate(
{
	opacity: 1
}, 1500);

This animation simply fades the background into view by changing the opacity to 1. We already know that the next background is going to be invisible because in showcaseBanner we set all elements with the class of background to opacity:0;. This is commented out at the moment, so you could see what you were doing in the last blog, so now would be a great time to uncomment those lines in the showcaseBanner function:

// Hide all banners
$(banner_list + " li").css({ display: 'none'});
$(banner_list + " .background").css({opacity: '0'});

Next are all the animations that bring the elements in to the slides, followed by the animations that take them back out again. I’ve included a couple more than we’ve used in this tutorial, so feel free to try them out in your spare time. The concept of each animation is very similar, so I'm choosing one here to illustrate how it works, but the principle can be applied to the other animations, as I'll explain later.

Wipe left and right

Wipe left and wipe right are to do with animations appearing from the sides of the banner. Wipe left will appear and disappear from the left side of the screen, while wipe right will do the opposite.

Animate in

So let’s start by getting the elements to animate into the banner. Firstly, we search from any elements that contain the name of the animation. (In this case wipe-left)

$wipe_in_left_element = $next.find('.wipe-left');

We then get the element’s left position, which will signify where the animation will stop when it’s inside the banner. jQuery will spit this out as a string, so be sure to convert it into an int using the standard JavaScript function parseInt.

$wipe_in_left_position = $wipe_in_left_element.css('left'); //finish position
$wipe_in_left_position = parseInt($wipe_in_left_position); //convert to int from string

We store the position that the element will stop inside the banner, as we’re now going to move the element outside the banner, ready to be animated. We know, in the case of swipe left, the side we’re going to animate in and out of is the left side, so we set the position of the element to left:0. This however only places the element hard against the left side of the banner area, with the whole element still showing. To get the element outside of the banner area, we need to also move the element further left by the the amount that the element is wide. So, we find out what the width of the element is, and make the left position minus that amount. This should set it nicely outside the banner area.

$wipe_in_left_element.css({left: -$wipe_in_left_element.outerWidth()}); //starting position

Next we let jQuery know we want to perform an animation on an element. We then specify that it’s the left position that we want to animate, and to what position it’s going to animate to. As we’ve already moved the element to it’s starting position, (outside the banner area), the element will now animate from there all the way to it’s destination inside the banner area.

$wipe_in_left_element.animate({
	left: $wipe_in_left_position
}, 1100, function(){
	$wipe_in_left_element.attr('style', '');
});

After the animation is complete we then make sure we remove any of the inline styles that are applied to the element by jQuery’s animation. This means that our stylesheet once again takes over the positioning of the element inside the banner, and isn’t being overridden.

$wipe_in_left_element.animate({
	left: $wipe_in_left_position
}, 1100, function(){
	$wipe_in_left_element.attr('style', '');
});

Why do we do this? Well, it’s all about keeping it responsive. You see, the positioning of the element in the style sheet is done by percentages... but jQuery’s animation works in pixels. Pixels are fine for animating, but if we leave the pixel based styles on the elements, they will no longer respond to the size of the browser window if it’s changed. Having removed the inline styles from the element, if the browser does change size, the CSS percentage based positions take over, and the calculations involved to animate the element back out of the screen will have the correct positions to start from.

Animate Out

So let’s animate the element back out of the banner area. The concept is very similar. We know where we’re animating from, as the element is currently sitting in that location, so we just need to know where we’re going to animate to. So like last time, first find the element.

//wipe left
$wipe_out_left_element = $active.find('.wipe-left');

Then calculate where the end position is going to be; which for wipe left is left:0 minus the width of the element.

$wipe_out_left_position = $wipe_out_left_element.css('left'); //finish position
$wipe_out_left_position = parseInt($wipe_out_left_position) - $wipe_out_left_element.outerWidth(); //convert to int from string

It’s then time to animate the element, remembering to again remove the inline styles afterwards. Removing the inline styles this time will move the element back into the banner area, but by the time that happens that slide will have been made invisible, so you will not be able to see it.

$wipe_out_left_element.animate({
	left: $wipe_out_left_position
}, 1500, function(){
	$wipe_out_left_element.attr('style', '');
});

The other animations work in a very similar fashion, the only difference being that they animate in and out of a different side of the slide, so I won’t go over them now as i’ll just be repeating myself. They are in the code file for you to have a look at though, so do check them out. The last part of this function checks to see if the current slide has a background image.

//Background out and hide the previous banner
$active_background = $active.find('.background');

If it does find a background, then it animates it out by making it expand and fade. We do this by using the height and width of the background, and animating it to twice the size. To make it appear to fade out, we use the opacity parameter and set it to 0.

if($active_background.length > 0)
{
	$active_background.animate({

		opacity: 0,
		height: $active_background.outerHeight()*2,
		width: $active_background.outerWidth()*2,
		left: -$active_background.outerWidth()/2,
		top: -$active_background.outerHeight()/2

	}, 1500, function(){
		$active_background.attr('style', 'opacity:0;');
		$active.css('display', 'none');
		$active.css('z-index', '1');
		$active.removeClass('active');
	});
}
else
{
	$featured_banner = $active.find('.featured-banner');
	$featured_banner.animate({
		left: 0
	}, 1500, function(){
		$featured_banner.attr('style', '');
		$active.css('display', 'none')
		$active.removeClass('active');
	})
}

Once the animation is finished, we then remove the inline styles set by the jQuery animation, hide the slide, and change it’s z-index so that it sits behind the next slide. Finally we remove the active class from the slide, so that we now know that this is no longer the slide that’s being shown.

if($active_background.length > 0)
{
	$active_background.animate({
		opacity: 0,
		height: $active_background.outerHeight()*2,
		width: $active_background.outerWidth()*2,
		left: -$active_background.outerWidth()/2,
		top: -$active_background.outerHeight()/2
	}, 1500, function(){

		$active_background.attr('style', 'opacity:0;');
		$active.css('display', 'none');
		$active.css('z-index', '1');
		$active.removeClass('active');

	});
}
else
{
	$featured_banner = $active.find('.featured-banner');
	$featured_banner.animate({
		left: 0
	}, 1500, function(){
		$featured_banner.attr('style', '');
		$active.css('display', 'none')
		$active.removeClass('active');
	})
}

Of course, if there is no background image, then we just need to hide the slide. To make sure that we don’t hide the slide before all the animations for the elements have finished, we'll use an animation function on the banner itself, with the duration set to the same value as it would be if there were a background. Set the left value to 0, which is what it is already, so no animation appears to happen, but what we do end up with is the correct delay that is needed. Once the delay has happened, we then again remove the inline styles applied by the jQuery animation, hide the slide, and remove it’s active class.

if($active_background.length > 0)
{
	$active_background.animate({
		opacity: 0,
		height: $active_background.outerHeight()*2,
		width: $active_background.outerWidth()*2,
		left: -$active_background.outerWidth()/2,
		top: -$active_background.outerHeight()/2
	}, 1500, function(){
		$active_background.attr('style', 'opacity:0;');
		$active.css('display', 'none');
		$active.css('z-index', '1');
		$active.removeClass('active');
	});
}
else
{

	$featured_banner = $active.find('.featured-banner');
	$featured_banner.animate({
		left: 0
	}, 1500, function(){
		$featured_banner.attr('style', '');
		$active.css('display', 'none')
		$active.removeClass('active');
	})

}

Now, it’s all well and good that you’ve got these animations, but how do you use them? Well the eagle-eyed among you will have noticed the animations look for certain classes on your banner elements. So what we need to do is go back to our html for the slides, and add classes based on the animations we want to have.

<li data-banner-number="1">
	<a href="/portfolio/daymedia/" class="featured-banner">
		<img class="background" src="/images/blue-bg-photo.png" />

		<div class="daymedia">
			<h2 class="heading fade">Expertly Crafted Design</h2>
			<img class="logo fade" src="/images/dm-logo.png" alt="Daymedia Logo" />
		</div>
	</a>
</li>


<li data-banner-number="2">
	<a href="/portfolio/daymedia-2/" class="featured-banner">
		<div class="daymedia-two fade">
			<div class="design wipe-right"><img src="/images/print-design.png" alt="Print Design" />Logo Design & Branding</div>
			<div class="web-dev peek"><img src="/images/web-dev.png" alt="Web Development" />Web Development</div>
			<div class="e-com wipe-left"><img src="/images/e-com.png" alt="E-commerce" />Online Shopping</div>
		</div>
	</a>
</li>

You’re almost there, we just need to trigger the banner to start when the page has finished loading and set the speed that the banners change. So in your JavaScript file, add the following line of code:

showcaseBanner(".banner-slider", 10000);

That’s it! You should now be looking at a banner that has some custom animation, is responsive, and has the potential to be unique to your website. Enjoy!