Welcome to Part 2 of my YUI Carousel series. This part uses class names to setup multiple carousel instances, and also drops the YUI CSS in favour of writing your own custom css. The final Part 3 will show you how to ditch the YUI navigation completely, so that you can use custom labels.
I recommend that you read Part 1 of this tutorial if you haven’t already. If you want to follow along, then please setup your workspace with a basic HTML file and somewhere to put Javascript, CSS & images now, the demonstration page is here. I’ll be using the same images as last time, same rules apply!
Getting Started – The HTML
The HTML for the carousel is the same as in Part 1, except this time I have added titles to my images. Below I’ve only listed one carousel, but as you can see on the demonstration page, the setup JavaScript we’ll be writing later will detect multiple carousels on the page. To add another carousel just copy the HTML structure including the container div, change the id’s but leave the classes intact.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <body class="carousel"> <div id="my-carousel" class="carousel-container"> <ol class="carousel-content"> <li> <img src="http://farm3.static.flickr.com/2181/3529457733_50200b99ab.jpg" width="500" height="364" alt="Baby Dolphin" /> <h2>A Baby Dolphin called Bob</h2> </li> <li> <img src="http://farm4.static.flickr.com/3543/3514480796_2243d70d6b.jpg" width="500" height="364"alt="Birds" /> <h2>Feeding the birds</h2> </li> <li> <img src="http://farm4.static.flickr.com/3306/3503294318_c34fab9d17.jpg" width="500" height="364" alt="Tiger" /> <h2>Up close and personal with a tiger</h2> </li> </ol> </div> </body> |
Referencing YUI
You’ll need to add the same JavaScript references right above your closing body tag as last time. That is the link to the combined YUI scripts, plus your own setup JavaScript file. This time though, DON’T include the YUI CSS, just add a link to your own CSS file at the top of the page. So these are the includes you should have:
1 2 3 4 5 6 7 8 9 | <head> <link rel="stylesheet" type="text/css" href="css/carousel.css" /> </head> <body> <!-- Content here --> <script src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo-dom-event/yahoo-dom-event.js&2.7.0/build/element/element-min.js&2.7.0/build/animation/animation-min.js&2.7.0/build/carousel/carousel-min.js" type="text/javascript"></script> <script src="js/carousel.js" type="text/javascript"></script> </body> |
Setting up – Javascript
Step 1 – Locate all carousel markup on the page
The first step is the same as last time, to setup our namespace and object literal. We still need an init function, and inside it we use the getElementsByClassName function to populate our carousels property with an array of all the elements which have the class carousel-container. We then loop over carousels and call a setup function on each element.
1 2 3 4 5 6 7 8 9 10 11 | YAHOO.namespace("ErisDS"); YAHOO.ErisDS.Carousel = { carousels: '', init: function() { this.carousels = YAHOO.util.Dom.getElementsByClassName('carousel-container'); for(i = 0; i < this.carousels.length; i++) { this.setup(this.carousels[i]); } }, ... |
Step 2 – Turn carousel markup into working carousels
Now we need to write our setup function. It takes the element that is to be a carousel as an argument. The body of the function contains the same setup code as our original init function from Part 1, where the settings are explained.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | setup: function(carousel_el) { var carousel = new YAHOO.widget.Carousel(carousel_el, { autoPlayInterval: 5000, isCircular: true, animation: { speed: 1.0 }, numVisible: 1 }); carousel.render(); carousel.show(); carousel.startAutoPlay(); } |
Finally, don’t forget to call the function using onDOMReady().
1 2 3 4 5 | YAHOO.util.Event.onDOMReady( function (ev) { YAHOO.ErisDS.Carousel.init(); } ); |
Styling up - The Custom CSS
This time we aren't going to use the YUI CSS at all, so we will need to do quite a bit of work ourselves. First up I'll show you the bare minimum needed to get the carousel working. Then we will go through styling the navigation, and finally the customisations to get it looking the same as the demo page.
The Bare Minimum
To get the carousel working horizontally, we need to get all the items to display side-by-side. We then need to hide all but the item that should be visible using overflow:hidden. We also need to clear margins and padding, but we don't need to set any width or height - the carousel will just resize to fit the largest element inside of it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | .carousel .carousel-container{ overflow: hidden; position: relative; margin: 0; } .carousel ol.carousel-content{ position: relative; overflow: hidden; width: 32000px; padding: 0; margin: 0; } .carousel ol.carousel-content li{ position: relative; margin: 0; float: left; overflow: hidden; *float: none; *display: inline-block; *zoom: 1; *display: inline; } |

I can hear people all over the interweb screaming "nooooo!" at the IE hacks. Feel free to move these to conditional comments, but for the purpose of tutorials using hacks makes it easier to show what I'm doing! All that extra code (plus the position:relative's) is used to get IE6 & 7 to display the items side-by-side whilst still hiding all but the first item.
On the right you can see how the carousel looks with just this basic styling - pretty nasty! Time to get creative. I want to get rid of the text in the navigation, put the navigation at the bottom, and add some nicer buttons*.
The Navigation
Because I want to put the navigation at the bottom & have my carousel be fixed size, I need to set width and height on carousel-container and on the content li. I'm also going to add a border to contain the carousel. The following is the extra CSS I added.
1 2 3 4 5 6 7 8 9 10 | .carousel .carousel-container{ width: 500px; height: 364px; border: 5px #451669 solid; } .carousel ol.carousel-content li{ width: 500px; height: 364px; } |
The following code uses position:absolute to move the navigation to the bottom. I've also added a semi-transparent background to the navigation bar, and used the inline-block hack again to get the UL to sit in the middle for all browsers. In the second part I have turned the navigation into circles using the CSS3 border-radius property (IE users will see squares) & gotten rid of the text with positioning.
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 | .carousel .yui-carousel-nav{ position: absolute; bottom: 0; left: 0; right: 0; z-index: 300; width: 500px; text-align: center; height: 31px; line-height: 30px; background: transparent url('../images/bg.png') top left repeat; } .carousel .yui-carousel-nav ul{ margin: 5px 0; padding: 0px; display: inline-block; *display: inline; zoom: 1; vertical-align: middle; list-style: none; } .carousel .yui-carousel-nav ul li{ float: left; height: 8px; width: 8px; background: #673191; margin: 5px; border: 1px solid #673191; -moz-border-radius: 5px; cursor: pointer; } .carousel .yui-carousel-nav ul li a{ left: -10000px; position: absolute; } .carousel .yui-carousel-nav ul li:hover, .carousel .yui-carousel-nav ul li.hover, .carousel .yui-carousel-nav ul li.yui-carousel-nav-page-selected { background: #b6a2c4; cursor: pointer; } |
Next let's replace those ugly buttons with something else. By setting the width, height and padding of the button we can hide it. Then I've added a background image to the spans and absolutely positioned them. I have also been adding hover states to all the navigation, but at the moment these will only work in browsers that support the :hover psuedo class on elements other than the anchor tag.
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 | .carousel .yui-carousel-nav span{ position: absolute; bottom: 3px; width: 25px; height: 25px; } .carousel .yui-carousel-nav span button, #carousel-2 .yui-carousel-nav span button:focus{ background: transparent; border: none; padding: 30px 0 0; width: 25px; height: 25px; cursor: pointer; } .carousel .yui-carousel-nav span.yui-carousel-first-button{ left: 170px; background: url('../images/prev-arrow.gif') no-repeat top left; } .carousel .yui-carousel-nav span.yui-carousel-next-button{ right: 170px; background: url('../images/next-arrow.gif') no-repeat top left; } .carousel .yui-carousel-nav span.yui-carousel-first-button:hover, .carousel .yui-carousel-nav span.prev-hover{ background: url('../images/prev-arrow-hover.gif') no-repeat top left; } .carousel .yui-carousel-nav span.yui-carousel-next-button:hover, .carousel .yui-carousel-nav span.next-hover{ background: url('../images/next-arrow-hover.gif') no-repeat top left; } |
We can fix the hover states for the previous and next buttons with some Javascript, but I haven't found a way to get this to work for the list navigation yet as it gets rewritten everytime the carousel changes and therefore it loses the listeners. To add listeners to the buttons, first add the following code to the end of your init function.
1 2 3 | var nav_buttons = YAHOO.util.Dom.getElementsByClassName('yui-carousel-button','span'); YAHOO.util.Event.addListener(nav_buttons,'mouseover',this.mouseover); YAHOO.util.Event.addListener(nav_buttons,'mouseout',this.mouseout); |
Next, after the setup function add a comma, and then add the following two functions. All this does is add a class on mouseover and then remove it on mouseout, we use two different classes to make it easier to reference the buttons in IE6. This could be replaced with a sprite image & CSS that just changes the background position.
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 | mouseover: function(e) { var add_target = YAHOO.util.Event.getTarget(e, false); //add_target = YAHOO.util.Dom.getAncestorByTagName(target,'span'); if(YAHOO.util.Dom.hasClass(add_target, 'yui-carousel-next-button')) { YAHOO.util.Dom.addClass(add_target, 'next-hover'); } else if(YAHOO.util.Dom.hasClass(add_target, 'yui-carousel-first-button')) { YAHOO.util.Dom.addClass(add_target, 'prev-hover'); } }, mouseout: function(e) { var rem_target = YAHOO.util.Event.getTarget(e, false); //rem_target = YAHOO.util.Dom.getAncestorByTagName(target,'span'); if(YAHOO.util.Dom.hasClass(rem_target, 'next-hover')) { YAHOO.util.Dom.removeClass(rem_target, 'next-hover'); } else if(YAHOO.util.Dom.hasClass(rem_target, 'prev-hover')) { YAHOO.util.Dom.removeClass(rem_target, "prev-hover"); } } |
Headings
That's it for the functionaliy. Here's the CSS I used to style my main heading. It's almost identical to the nav-bar code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .carousel ol.carousel-content li h2{ position: absolute; top: 0; left: 0; right: 0; width: 500px; z-index: 300; line-height: 28px; background: transparent url('../images/bg.png') top left repeat; color: #fff; margin: 0px; padding: 5px; text-align: center; } |
On the demo page, the two carousels are the same size and styled very similarly. However this is not necessary as you do not need to specifiy the size (the carousel will default to the size of the largest item within it) and you can also use id's to style the two carousels entirely differently in the CSS, yet still use the same Javascript to make them work. However the functionality for the two carousels would remain the same.
Well I think that's a wrap! Not every single bit of CSS I used is here, but I will be providing all my files which I publish Part 3 next week some time. Hope you've found this useful & reasonably easy to follow. Please drop any suggestions or ideas in the comments!
* I said nicer, not amazing... I'm no designer!!
Resources
- Visit the API for a full list of available methods, properties and attributes.
- YUI Dependency Configurator
- The demo page (2)


4th Aug
yy1993 says:
Not bad. Will try it next time.
4th Aug
pfwd says:
Looks good. Haven’t done much in YUI but worth a bookmark for the future
4th Aug
Rob Mason says:
Good tutorial. personally prefer jQuery, but when I get internetz back at home I’ll give this a whirl.
4th Aug
YUI: Javascript Carousel with Custom Navigation - Part I | Musings of ErisDS pinged back:
[...] the HTML, CSS & Javascript needed to setup a basic carousel using the YUI default skin. In Part 2 we’ll remove the YUI skin and write our own, introduce multiple instances via class names and [...]
5th Aug
Free JavaScript Code says:
very cool & good tip, thank you very much for sharing.
6th Aug
ErisDS says:
People seem to get put off by YUI because of it’s scale and how different it is to other frameworks. I wasn’t so keen myself originally. However, after having worked with it quite a bit, I really love it. I like Prototype too, but often it just doesn’t have the flexibility which I need.
Has anyone actually tried out this tutorial (or just the first part) yet? I’d love to hear some feedback on whether or not it is easy to follow or if anyone had any issues!
11th Aug
Don says:
Hello ErisDs,
Your script works like a charm and is just what I need. It took awhile to figure where the underlying code was since you use WordPress and decided to “hide” your yummy “carousel.js”. I suggest you highlight this code and maybe submit it to YahooUI. It’s a great code example, keep it up!
Cheers,
Don
11th Aug
ErisDS says:
Hi Don :)
Thanks for your kind words. I promise I’m not deliberately hiding anything! All of my code will be available to download/on GitHub once the last part of this tutorial is published sometime soon.
I am a bit behind schedule this week because I moved my blog over the weekend. Part 3 will be done in the next week. Then everything will be revealed, but before that the carousel.js & carousel.css files are not complete.
11th Aug
In the Wild for August 10, 2009 » Yahoo! User Interface Blog pinged back:
[...] on WAMU.org: WAMU (American University Radio) has a nice Google Maps mashup using YUI Buttons.YUI Carousel Value-adds from ErisDS: Blogger ErisDS has posted two parts of what will be a three-part series on implementing custom [...]
30th Aug
Naren says:
Hello Eris,
Lovely job in transforming the look of the YUI carousel. Your customization has made it look much better and ‘usable’. Thanks a lot for the tips.
I second Don’s statement. You have to submit this to YUI. Great work.
Cheers,
Naren.
3rd Sep
Chris says:
Thanks Eris
Great article on the YUI carousel – was just what I was looking for.
8th Oct
Tom says:
I used your tutorial to set up the yahoo gallery here:
(site is in development — not live yet)
http://vps3313.inmotionhosting.com/~designl/productgallery.php
I’m having 2 issues. One is that I want the user to be able to popup a large image in a CSS window when they click on a picture. I’ve tried a few CSS tricks that I know, but they happen within the frame of the image within the carousel. Is there an easy way to get an image to popup?
2nd, I am fine on IE8 and Firefox, but the carousel is thrown off in IE7. You can see all my code on the URL.
Would you mind helping me a bit?
thanks,
-Tom
9th Oct
ErisDS says:
Hi Tom,
Not at all, I’ll take a look over the weekend and get back to you :)
Eris
11th Oct
Nagarajan says:
Hi everyone ,
even though i use the exact code presented heer i am not getting the carousel. I tried for one full day.
13th Oct
ErisDS says:
Hi Nagaran,
Please use my contact form to get in touch or otherwise provide a link to your code so I can take a look and figure out what went wrong :)
Eris
3rd Nov
Karl says:
Still eagerly awaiting Part 3, now in November…
3rd Nov
ErisDS says:
@Karl I’m so sorry! Having my house rewired has really thrown a spanner in the works. I didn’t know there was anyone specifically waiting though – will get the next article out ASAP.
11th Nov
Karl says:
Eris, have you been able to work with other types of transitions? I’d like to see a cross-fade between the pictures, instead of a scrolling animation. Not sure that’s possible, though!
Thanks :)
13th Jan
tfrancis says:
Totally confused can you just compile the whole steps together for easy download/testing. That’ll be appreciated. Thanks
13th Jan
ErisDS says:
@tfrancis: I’m very sorry to hear you are confused by this post. Have you read the first part in the series? If you let me know what has confused you I can try to help out. I will make a download available as soon as possible.
25th Mar
bob says:
Great work and the best multi-carousel tutorial i’ve seen thus far.
Quick question: from a purist point of view ( not to say I am one :) ), is there a functional reason why you’re using ‘carousel-2′ for 2 separate id attributes on the demo page or is this just for your own styling purposes? Thanks and keep up the great work!
25th Mar
ErisDS says:
Hi Bob,
Ah.. that’s just a bugger up on my part because I have two examples of carousel 2. It doesn’t need an ID attribute to work in practice, but my demo code uses it so as to keep my separate examples (1, 2 and 3 which isn’t published) really separate. When I wrote the article I thought “oh I’ll demo it this way too” copy, paste, didn’t think about it being duplicate ids!
2nd May
Sargis Dallakyan says:
Thanks a lot for the tips. I was searching to skin yui-carousel to put the navigation at the bottom and this post was very helpful. I have an example of this on my site: http://food-prints.appspot.com