Coding a Rotating Image Slideshow w/ CSS3 and jQuery

Coding a Rotating Image Slideshow w/ CSS3 and jQuery

Today we are going to use jQuery and CSS3 rotations, along with the jQuery rotate plugin, to create a beautiful slideshow. You can use it to spice up your web sites, product pages and other projects with some CSS3 magic.

HTML

Following the tradition, we will first lay down the HTML markup of the slideshow. The main container element is the #slideShowContainer div, which holds the #slideShow div and the previous / next links (turned into arrows with CSS).

index.html

<!DOCTYPE html>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Rotating Slideshow With jQuery and CSS3 | Tutorialzine Demo</title>

<link rel="stylesheet" type="text/css" href="css/styles.css" />

</head>
<body>

<div id="slideShowContainer">

    <div id="slideShow">

    	<ul>
            <li><img src="img/photos/1.jpg" width="100%" alt="Fish" /></li>
            <li><img src="img/photos/2.jpg" width="100%" alt="Ancient" /></li>
            <li><img src="img/photos/3.jpg" width="100%" alt="Industry" /></li>
            <li><img src="img/photos/4.jpg" width="100%" alt="Rain" /></li>
        </ul>

    </div>

    <a id="previousLink" href="#">»</a>
    <a id="nextLink" href="#">«</a>

</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="js/jquery.rotate.js"></script>
<script src="js/script.js"></script>

</body>
</html>

The slides are defined as LI elements inside of an unordered list. Notice that the width of the images is set to 100%. This way they will scale according to the width of the #slideShow div.

At the bottom, we include the jQuery library, our own script.js file, and the jQuery rotate plugin. We are using the plugin, so we can work with CSS3 rotations in a cross-browser fashion, as you will see in the last step of this tutorial.

The Slideshow Markup

The Slideshow Markup

CSS

This layout relies heavily on relative and absolute positioning. You can see the styling of the slideshow below.

styles.css

#slideShowContainer{
	width:510px;
	height:510px;
	position:relative;
	margin:120px auto 50px;
}

#slideShow{
	position:absolute;
	height:490px;
	width:490px;
	background-color:#fff;
	margin:10px 0 0 10px;
	z-index:100;

	-moz-box-shadow:0 0 10px #111;
	-webkit-box-shadow:0 0 10px #111;
	box-shadow:0 0 10px #111;
}

#slideShow ul{
	position:absolute;
	top:15px;
	right:15px;
	bottom:15px;
	left:15px;
	list-style:none;
	overflow:hidden;
}

#slideShow li{
	position:absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
}

#slideShowContainer > a{
	border:none;
	text-decoration:none;
	text-indent:-99999px;
	overflow:hidden;
	width:36px;
	height:37px;
	background:url('../img/arrows.png') no-repeat;
	position:absolute;
	top:50%;
	margin-top:-21px;
}

#previousLink{
	left:-38px;
}

#previousLink:hover{
	background-position:bottom left;
}

a#nextLink{
	right:-38px;
	background-position:top right;
}

#nextLink:hover{
	background-position:bottom right;
}

Although the #slideShow div is set to a width of 490px, its full size is actually 510px. This 20px difference scales down the slide images (as they are locked to the width of the #slideShow div), which are reduced from their normal size of 480px down to 460px. As you will see in the next step, we are using a jQuery animation to zoom in the slideshow to its full size. This way, even at full zoom, the images are actually at their regular size and there is no loss of quality.

jQuery CSS3 Rotating Slideshow

jQuery CSS3 Rotating Slideshow

jQuery

Although most modern browsers support CSS3 rotation, it is still rather tedious to work with the various vendor-specific properties. Luckily, there are plugins available that handle the cross-browser nonsense for us. I chose the jQuery rotate plugin, as it also integrates perfectly with the animate() and css() methods of the library, which means we can easily animate the rotation of elements. As you will see in a moment, we are using this in our custom rotateContainer event, which rotates the #slideShow div.

script.js – Part 1

$(document).ready(function(){

	var slideShow = $('#slideShow'),
		ul = slideShow.find('ul'),
		li = ul.find('li'),
		cnt = li.length;

	// As the images are positioned absolutely, the last image will be shown on top.
	// This is why we force them in the correct order by assigning z-indexes:

	updateZindex();

	if($.support.transform){

		// Modern browsers with support for css3 transformations

		li.find('img').css('rotate',function(i){
			// Rotating the images counter-clockwise
			return (-90*i) + 'deg';
		});

		// Binding a custom event. the direction and degrees parameters
		// are passed when the event is triggered later on in the code.

		slideShow.bind('rotateContainer',function(e,direction,degrees){

			// Zooming in the slideshow:

			slideShow.animate({
				width		: 510,
				height		: 510,
				marginTop	: 0,
				marginLeft	: 0
			},'fast',function(){

				if(direction == 'next'){

					// Moving the topmost image containing Li at
					// the bottom after a fadeOut animation

					$('li:first').fadeOut('slow',function(){
						$(this).remove().appendTo(ul).show();
						updateZindex();
					});
				}
				else {

					// Showing the bottommost Li element on top
					// with a fade in animation. Notice that we are
					// updating the z-indexes.

					var liLast = $('li:last').hide().remove().prependTo(ul);
					updateZindex();
					liLast.fadeIn('slow');
				}

				// Rotating the slideShow. css('rotate') gives us the
				// current rotation in radians. We are converting it to
				// degrees so we can add +90 or -90.

				slideShow.animate({
					rotate:Math.round($.rotate.radToDeg(slideShow.css('rotate'))+degrees) + 'deg'
				},'slow').animate({
					width		: 490,
					height		: 490,
					marginTop	: 10,
					marginLeft	: 10
				},'fast');
			});
		});

		// By triggering the custom events below, we can
		// show the previous / next images in the slideshow.

		slideShow.bind('showNext',function(){
			slideShow.trigger('rotateContainer',['next',90]);
		});

		slideShow.bind('showPrevious',function(){
			slideShow.trigger('rotateContainer',['previous',-90]);
		});
	}

I am using jQuery’s $.support object to test whether the visitor’s browser supports CSS3 transformations. We are only going to display the rotation in browsers with transformation support, like the newer versions of Firefox, Chrome, Safari and Opera, while falling back to a plain fade in/out version of the slideshow in the rest.

Internet Explorer does provide a solution for rotating elements via its proprietary filter syntax, but it can’t handle the technique we are using for this slideshow. So, in effect, you are going to see a working slideshow in any browser, but only enjoy the fancy version in those that have support for it.

In the code above, you can see that we are binding a number of custom events. showNext and showPrevious are what we are using to control the slideshow. These in turn execute the rotateContainer event, and pass the direction and degrees as parameters (you could merge them into a single parameter, but I find it clearer this way).

A Rotating Slideshow With jQuery and CSS3

A Rotating Slideshow With jQuery and CSS3

script.js – Part 2

	else{
		// Fallback for Internet Explorer and older browsers

		slideShow.bind('showNext',function(){
			$('li:first').fadeOut('slow',function(){
				$(this).remove().appendTo(ul).show();
				updateZindex();
			});
		});

		slideShow.bind('showPrevious',function(){
			var liLast = $('li:last').hide().remove().prependTo(ul);
			updateZindex();
			liLast.fadeIn('slow');
		});
	}

	// Listening for clicks on the arrows, and
	// triggering the appropriate event.

	$('#previousLink').click(function(){
		if(slideShow.is(':animated')){
			return false;
		}

		slideShow.trigger('showPrevious');
		return false;
	});

	$('#nextLink').click(function(){
		if(slideShow.is(':animated')){
			return false;
		}

		slideShow.trigger('showNext');
		return false;
	});

	// This function updates the z-index properties.
	function updateZindex(){

		// The CSS method can take a function as its second argument.
		// i is the zero-based index of the element.

		ul.find('li').css('z-index',function(i){
			return cnt-i;
		});
	}

});

In the second part of the code, you can see the fragment that is executed only in browsers that do not support CSS3 transformations. Notice that in this case, we also define the same showNext and showPrevious events, but here they just fade in / out the images, without starting a rotation.

The updateZindex() function is important, as otherwise the slides would be displayed in reverse order. This function loops through the elements in the order they currently are, and assigns a z-index property, so they are displayed correctly.

With this our Rotating Slideshow is complete!

Conclusion

Using jQuery we created a beautiful rotating slideshow, with which you can showcase your images and add a bit of interactivity to your pages.

How would you improve this example? Be sure to share your thoughts in the comment section below.

Join our newsletter and get our PSDs!18,476 people learn about HTML5, JS and more. Join them!

by Martin Angelov

Martin is a web developer with an eye for design from Bulgaria. He founded Tutorialzine in 2009 and it still is his favorite side project.

43 Comments

  1. Assasain14 says:

    Nice tutorial as always.

  2. rajesh says:

    very nice piece of work thanks for the tutorial

  3. Eduardo says:

    Awesome technique. Will definitely incorporate this on a future website!

  4. Bogdanel says:

    Very nice slideshow effect! Bookmarked!

  5. Vedran says:

    Nice example and good to see and learn how to write proper code. But don't think I could use it in any of my projects, just too playful.

    I discovered that the people want a simple gallery. even the good "old" lightbox gallery is somehow too much.

  6. Codeforest says:

    All I can say is great tutorial.

    Very nice use of Javascript closure in UpdateCSS function.

  7. aditya says:

    its really cool.........i like it.
    thank u........
    i like to learn such new things...........

  8. This is a really great tutorial.. thanks..!!

  9. Ryan Turki says:

    Great Tut !!!

  10. Curtis Scott says:

    Great tutorial as usual! I hope to try this out my portfolio page.

    Thanks for sharing!

  11. laboratory says:

    Unusual way to show pictures in the slideshow.

    However there are not many websites where that kind of slideshow could be used.
    Of course I'm aware that this is not the only effect that can be used:)

    Cheers.

  12. sager says:

    Rotating don't work on Internet Explorer 9.

  13. ZH CEXO says:

    Awesome, but not very smooth in Firefox
    I like this tutorial very much

  14. Beben Koben says:

    hohohoho...its a cool
    thanks^^

  15. Zach says:

    Check out the awesome twitpic gallery I made using this! http://zackify.net/twitgallery/

  16. Paweł P. says:

    WOW! Great tutorial.
    It looks the best in Safari (impressive)
    Best regards!

  17. Denis says:

    amazing :)

    Look really amazing :)

  18. Sharun Kumar says:

    This is awesome !!!!!!!!!!!!

  19. Mandi says:

    Great tutorial and great rotating css 3 and jquery effect I love it for one of my sites, thank you!

  20. Maicon says:

    Very beautiful effect. Your site rocks!

  21. Kevin says:

    That's a very nice gallery, really nice transition. Thanks.

  22. hello, how I can do to automatically change the image every 30 seconds?

    1. Martin Angelov says:

      You might find this article interesting. If you follow the steps you should be able to make this slideshow auto-advance as well.

      1. no, do not succeed

  23. Rob Believe says:

    You could use this Jquery plugin to get the rotation working in IE as well:

    http://code.google.com/p/jqueryrotate/wiki/Examples

  24. Thien says:

    If you have other after the slider, the script will start removing the other on your page. To fix this,

    replace:

    var liLast = $('li:last').hide().remove().prependTo(ul);
    

    with:

    var liLast = $(ul.find('li:last')).hide().remove().prependTo(ul);

    in the:
    slideShow.bind('showPrevious',function(){

  25. Hi, Great tutorial and really nice affects. I'm having a problem, though, in the rotate.js -- in the function UpdateZindex() -- it's updating the z-index for ALL the ul's on the page preceding the /div that I want to be rotated. Any ideas on how to limit the z-index update to just the slideshow /div???

    1. SuperChunk says:

      Not sure if you figured it out, but I figured I'd post the solution as others may run into the same problem. Basically the script.js code was not correctly identifying which list items to make changes too. So you have to explicitly state it via the IDs.

      Make the following changes

      Declarations: var slideShow = $('#slideShow'),
      ul = $('#slideShow ul'),
      li = $('#slideShow li'),
      cnt = li.length;

      Line 41: $('#slideShow li:first').fadeOut('slow',function(){

      Line 89: $('#slideShow li:first').fadeOut('slow',function(){

      Line 96: var liLast = $('#slideShow li:last').hide().remove().prependTo(ul);

      1. SuperChunk says:

        Actually, you don't need to make the changes to the declarations area... just the three specific lines.

  26. joan says:

    thanks! i don't want the rotation, so i took out a chunk of code and still have a beautiful, functional slideshow (surprising how hard it can be to find that!).

  27. Simone says:

    I have a problem with the gallery if I usemore than of 8 pictures.
    Apparently the UpdateZindex() stop to work properly and I have a 90° rotation every time the user press the next button. You can see the problem if you test the demo.
    Any ideas?

    1. Claudio says:

      I also have the same problem, if I have more than 4 images at the end of the first cycle <li>, the second cycle, I see the images rotated by 90 ° in the direction, how do I fix this problem?

  28. I wanted to thank you for this! With some small jiggering, I managed to implement this for great effect for a client! It's a totally awesome script!

  29. PaulB says:

    Pretty cool scripting!

    I too am seeing odd rotation--I think a bit different from the above reports (using Firefox 13). With 18 images listed, going through the second time rotates them 180 degrees (and back to normal on a third go-round). Cutting back to four images results in a 90 degree rotation with each cycle.

    Also, I'm not crazy about the handling of non-square images, as I see either end of the next image crisscrossed underneath the present image at any given time. Is there any way to eliminate this (without just cropping my images to squares)?

  30. nadeem ahmed says:

    hello

    can we use this for both personal and commercial for free?

    Thanks & Regards
    Nadeem

  31. I am having the flip problem with over four graphics as well, sorry to be doing a 'me too', but can anybody give me a fix, please?
    TIA
    Keith

  32. Alex says:

    Hi. I need to make this slide to autoplay.
    I am a beginer in javascript.
    Can somebady help me to make this script to autoplay? I meen this script.
    THX.

  33. shenlan51 says:

    very good,I like it

  34. Ypz says:

    First of all a big thanks for your effort! I have little knowledge of html&css (just started), but your tutorial helped me include a proper slideshow in my homepage. But I also have the problem, that the pics get rotated wrong after you went through the slideshow the first time. I tried to google the prob but with little to no success. Isnt there a way of defining the last picture in the slideshow as such, so the show would stop at the end?
    Please give me a little tip how to do it or where to look it up!
    Greetings from Germany!

  35. Martin says:

    Great script, but there is an error on line 41 of script.js.

    If I have more than one <ul> on my website it clone the first of it.

    It must be

    ul.children('li:first').fadeOut('slow',function(){
    	$(this).remove().appendTo(ul).show();
    	updateZindex();
    });
    

    instead of

    $('li:first').fadeOut('slow',function(){
    	$(this).remove().appendTo(ul).show();
    	updateZindex();
    });
    

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links