Creating a carousel with MooTools

You’ve probably seen it on various websites: those neat little inline slideshows that browse you through a gallery of images (or content if you want, too). Most people simply copy the code to use it on their own site, but I believe that by making it yourself, you learn new techniques and gain new insight. Therefore I’ll walk you through this tutorial that teaches you how to achieve this through the use of CSS and MooTools.

Getting started

Before heading off into the code, it’s best to think about how you’re going to tackle this. The Yahoo Design Pattern Library pretty much does this for you, but I’ll give it to you in brief in case you’d like to get started as soon as possible.

Basically, you’ll have an infinite list of items (obviously, you’ll want to expand or size down the list over time) which should be placed next to each other, horizontally. You’ll browse back and forth through them with 2 separate buttons. When the end is reached, you want the list to scroll back to the beginning and when you click back in the beginning, you want to be taken to the end.

This is all basic logical thinking. However, most people have problems with the method they have to use to display all those items.They don’t really know how to hide them or do it wrong, so their animations won’t work out the way they want them too. The idea on how you have to do this is actually pretty simple.

Setting up our HTML and CSS

The above layout shows you your basic structure. All the containers are lined up next to each other, only one container being displayed, the one in the yellow area; the rest is hidden with the help of CSS. We’ll start out with writing our HTML for this and then we’ll style it and add the MooTools effects.

The basic structure of your carousel element is this:

<div id="wrap">

	<ul id="carousel">
		<li><img src="image1.jpg" alt="Image 1" /></li>
		<li><img src="image2.jpg" alt="Image 2" /></li>

		<li><img src="image3.jpg" alt="Image 3" /></li>
		<li><img src="image4.jpg" alt="Image 4" /></li>

	</ul>
</div>

I can imagine some CSS gurus giving me a weird look when they see this code. At first sight it’s useless to add the additional #wrap container, but it’s actually the key to the whole script. The wrap is the actual width and height of the carousel and is in charge of hiding the content while the #carousel lines up all the elements on one line.

It’s impossible to achieve this effect with only one container, so we’ll resort to this. The rest of the markup is pretty self-explanatory: the <li> will act as containers for the images with a specified width and height to ensure that every element walks in line and displays like it should.

I haven’t added any next or previous links yet, since I’d like to make sure you focus on the how and why of this specific piece of code.

Next up, let’s throw some CSS on it to ensure that everything works smoothly.

#wrap {
	height:250px;
	width:450px;
	display:block;
	overflow:hidden;
	position:relative;
}

This CSS does two things: it specifies a width and height for the #wrap, the actual container of the carousel and it also tells your browser that it should cut off any content that doesn’t fit inside the window. The width and height are, obviously, the same width and height of one image. There is also a position declaration, because we’ll be positioning the #carousel through the use of position:absolute.This is one of the key elements in this script.

Because only the window of 250px by 450px is displayed, you can use the margins to make the elements transition through the window. There is however a couple more , just as important, things we have to do. Below that CSS, add the following:

#carousel {
	width:10000px;
	margin:0;
	padding:0;
}
#carousel li {
	height:250px;
	width:450px;
	margin:0;
	padding:0;
	float:left;
	display:inline;
}

A couple of things happen in this CSS code. We first set the width of the #carousel to 10000px. I just randomly picked this number, it doesn’t matter how big you choose, you just have to make sure that it’s larger than the width of all the elements combined. I also reset the margin and padding, to ensure that there’s no chance that images might be cut off.

The #carousel li sets the height and width of each individual container again and then floats them next to each other. I also added the display inline, even though modern users ignore it. It’s there to ensure that IE6 also displays it properly. I’ve seen plenty of occasions where, even though the images are floated, they still appear nest. This fixes that. I also reset the margin and padding here.

That’s all for the HTML and CSS, so far atleast. By now you should only have a container with one image, like this:

Setting up the effects with Mootools

Before starting up with the writing of our functions, include the mootools library. After you’ve done that, I’d like to define some basic variables. This is easy for me but even easier for you: if you want to customize the script, you’ll only have to change the variables to make the script do your bidding.

The basics

// Let's define some variables first
var wrapper = $('wrap'); // The outer wrapper
var carousel = $('carousel'); // The inner wrapper
var items = $$('#carousel li'); // The different elements, this is an array
var itemwidth = 450; // The full width of a single item (incl. borders, padding, etc ... if there is any)
var maxmargin = items.length * itemwidth - itemwidth;

I’ve added some comments to clarify what each variable stands for so this should be really easy to understand. I’m using the dollar-function which is widely known.

// Set up the animation
var animation = new Fx.Tween(carousel, {duration: 500});

This simple line sets up the animation we’ll use to slide our way through the images. I only added the duration option, but you can add several other options, explained here, to customize the equation, speed, etc … to your likings.

The ‘next’ and ‘previous’ links

Setting up the functions to browse forward and backward through the carousel is actually pretty easy. It simply requires some logical thinking. You simply add or substract the width of one element from the #carousel’s left property to go to the next or previous item. The only things that could cause problems would be that

  • if you’re browsing forward, you need to make sure that, when the last item is reached, the carousel is switched back to the start.,
  • if you’re browsing backward, you need to make sure that when they browse backwards from the first item, the carousel switches to the end.

Now that we’ve clarified that, let’s set up the code:

// The function to browse forward
function next_item(pos){
	if(pos == -max_margin){
		animation.start('left', 0);
	} else {
		var newposition = pos - item_width;
		animation.start('left', newposition);
	}
}

The function next_item is given the current position of an element and then changes the left property of an element so that the next item, from the right, is displayed. The conditional statement checks wether the last item is reached (the max_margin variable we declared earlier is the left position of the last item).

If the left position of the item is equal to max_margin, the left position is reset to 0; if not, a new position is calculated. Since we’re moving from left to right, we need to work with negative positions (therefor you’ll notice a couple of minus signs, this is basic math so I won’t go into much detail on this).

We simply tell our previously defined animation to start the effect: adjust the left position of the container to either 0 or to newposition. The newposition variable is calculated by substracting the item_width from the current position (pos).

The function for the previous item is pretty similar:

// The function to browse backward
function previous_item(pos){
	if(pos == 0){
		animation.start('left', -max_margin);
	} else {
		var newposition = pos + item_width;
		animation.start('left', newposition);
	}
}

Instead of checking that the max_margin is reached, this checks wether the first item is being displayed, for which the left position should then be 0. The math done here is pretty much the same aside from the fact that, since the carousel should move from right to left we need to add to the left position.

Still following? Excellent! Hold on a little longer, we’re almost there. Now we just need to set up the links to navigate through our little carousel. For this we’ll use the nifty addEvent function in Mootools.

// Set up the 'next' and 'previous' buttons
$('next').addEvent('click', function(){
	var position = parseInt(carousel.getStyle('left'));
	next_item(position);
});
$('previous').addEvent('click', function(){
	var position = parseInt(carousel.getStyle('left'));
	previous_item(position);
});

This snippet of code does 2 things, both very similar. It adds the event click to the elements with id’s next and previous. The element with id next triggers the next_item function, previous obviously triggers the previous_item function.

The only thing that might be confusing is the declaration of the variable position. It gets the left position of the carousel and then changes it to an integer (parseInt takes care of this). This variable is then given to the triggered function.

Wrapping it up

All that there is left to do, is add the next and previous links. These can be pretty much anything. You simply have to assign the right id’s and they’ll trigger the function: they can be links, paragraphs, titles, etc … anything you’d want them to do. As you’ll see on the page with the example, I simply styled links, which is only logical.

You’re now free to style the carousel any way you’d like. Unless you’re really capable with HTML and CSS and really understand what is going on, I’d recommend adding another additional container if you want to add padding, margin, border, etc … This is what I eventually ended up with, a nice and simple example.