Infinite Carousel Photo Gallery With CSS 3 & jQuery

/ CSS, Javascript, jQuery / by Paul Robinson / 71 Comments
This post was published back on February 26, 2011 and may be outdated. Please use caution when following older tutorials or using older code. After reading be sure to check for newer procedures or updates to code.

As I said the original inspiration behind this gallery is now gone, but the idea is still there. The gallery was basically an infinite carousel showing one image in the center with 1 half showing either side. I remember looking at the code used for it & thought there must be a simpler way to do it as it seemed extremely complicated. Then I realized the code was quite old and jQuery has come a long way since then, so here is my version of that photo gallery.

Infinite Carousel Gallery: Concept

The idea seems simple, a carousel of images that you can flip left or right through. The infinite part comes into play when you reach the last image. How? Well, when you do reach the last image the next image you see is the first image again. This let’s you flip through all the images without reaching an abrupt end.

I like the whole illustrate with images thing I’ve had going on in the last tutorial or two, so let’s keep it going. First let’s see what we are going to make, and you can try it out by clicking the demo below that. Just remember you’ll need an up-to-date version of a modern browser to view it at it’s best.

Now that you can see what we are going to be making, and you’ve had a chance to try it out let’s look at browser support.

  • Firefox 3.6 – Works with all features.
  • Chrome 11 – Works with all features.
  • Opera 11 – Works with all features.
  • Safari 5 – Works with all features.
  • Internet Explorer 8 – Animation works, however box shadow & scaling do not.
  • Internet Explorer 9 (RC) – Works with all features.

One small note about Internet Explorer 9. You must use the correct DOCTYPE or it will enter Quirks Mode & things will all go very strange. In HTML 5 you can use the DOCTYPE shown in the demo that’s:

Now that we’ve looked at potential browser problems let’s get onto the code that runs this bad boy. 😉

Infinite Carousel Gallery: HTML

First onto the HTML. I like to try to keep the HTML as simple as possible so bearing that in mind here is what I ended up with.

As normal you would replace the image paths, and the hyperlinks would point to the larger image. You’ll also need to provide a previous & next button although you can feel free to use the ones on the demo page.

A small, but very important, note is that your images must all be the same size. If they aren’t the CSS should auto resize them in proportion, however it looks neater if they are all the same size. It’s also best if they are all portrait images.

Infinite Carousel Gallery: CSS

There is quite a lot of CSS for this gallery, and a lot of it is needed for it to work properly. Let’s take a look and I’ll highlight the important lines.

First we need to look at some very important numbers that need to be set in the CSS. Unfortunately this is where a bit of complicated Maths comes into play. I’ll try to keep it as simple as possible though.

  • #photos_inner > width • Width of 1 list item (img + border) + left & right margin X 2
  • #photos_ul > left • (1 list item + left & right margin) + (half 1 list item + left margin)
  • #photos_ul li > width • width of 1 image + left & right borders
  • #photos_ul li img > width • The width of your images.

Those are the important sums that must be worked out correctly. If they aren’t you’ll probably find your animation won’t work & things will look a bit… Strange.

Here is a list of the other important parts that you probably won’t have to change, but are needed by jQuery to work properly.

  • #photos_inner > overflow • Hidden
  • #photos_ul > position • Relative
  • #photos_ul > list-style-type • none
  • #photos_ul > width • Must be nearly infinite 9999px is near enough
  • #photos_ul li > margin • Personal choice, but will help determine the values of the sums above
  • #photos_ul li img > border • Personal choice, but will partly determine the list item width

Everything else in the CSS is to help make it look nice, and the CSS 3 rules like box shadow & transform are not needed but when viewed in a browser that supports them it add that little bit of extra spice.

Infinite Carousel Gallery: jQuery

Now for the meaty bit. The jQuery code. This can get a little complicated so my sister over at Lisa Marie Art & Illustration has kindly created some information graphics to help out with the explanation.

First though here is the code in it’s entirety.

First a very important note. I animate the scale property here with jQuery, this is not natively available through jQuery and you will need to download the jQuery CSS Transform patch and the jQuery Animate for Rotate & Scale patch. You will also need to attach them after jQuery, and in that order. Huge thanks to Zachstronaut for making those patches.

Right, now let’s go through all this code piece by piece. I’ll ignore the DOM ready as it’s the same for most jQuery code.

This variable is one that could possibly need changing depending on how you are using the gallery. The only variable here is the path to the UL element containing the images. This can be customized freely. I have tried my best to make the code so that you will only need to change this single line if your UL has a different ID.

The first variable here stores your original left offset from your CSS. This is needed to make the carousel work properly later during the animation stage.

The second variable is just to help with the next sum. It tells it how many images are visible at one time, this includes the two half images either side. This cannot be changed yet as the code will most likely break due to how the infinite part of the carousel works. I’m working on that though.

The last variable here works out which numbered image will be at the center by taking the number of images visible and dividing it by 2, and rounding it up. This works because an odd number of items halved will always give you the number of the center item if you round the resulting decimal up.

Now comes the actual code. From now on I use the variable set before $car as context to select elements starting from the UL element we stored in the user variables earlier.

First we move the last two list items (images) to the front of the carousel. This is just in case the user presses previous first. This is partly the reason why you can’t increase the number of images displayed & needs to be looked at, but for the moment this is the best I’ve been able to come up with. I would have chained them, but for some reason they don’t work the same way & need to be two separate calls to before.

Next we use our patches to scale all the items down to 75% their original size. We have already done that in the CSS, however that is just to stop the flash before the jQuery has loaded. For some reason the jQuery patch does not recognize that you have already set the scale via CSS, so you must set it again here so we can animate it later.

Now we use the scaling again to scale up our center image back to 100%. This gives a nice circular carousel effect to our gallery by making the image on the left & right smaller than the center image. It’s also a lot easier than saying scale all the images except this one.

Now we can start setting up our click events. First our right button. I’ll skip the click binding since that is the same as normal. Obviously you will need to change the path to your right (and left) buttons if you wish, but that is up to you.

The first line of our click event grabs the outer width of our list item. This is the width of the element plus any border, and/or padding. Adding the true boolean also adds in margin, which is perfect for us.

The next line figures out the new left position for the animation by taking the list item width away from the current left position. Since out left position is negative subtracting from it actually adds to it and pushes our left position further into the negative, moving our list items further left.

Now we check to see if our UL is being animated (to stop crazy clickers from causing problems) and animate it to our new left position. Feel free to customize the animation timing although I think 500ms is nice.

Next in a callback function called when our animation finishes we place the first image in our list at the end of the UL. I’ll explain more with the infographics later but suffice to say it basically creates the infinite carousel effect.

Finally we push the left position back to the original offset. We need to do this since we have removed an item from the front meaning our left position no longer needs to take that item into account. Luckily that makes our original position correct again so we can just use that.

As for these last two lines; The first scales up the right image to 100% as it moves into the center, while the second line scales down the previous center image to 75% as it moves out to the left. How do we find the next and center image? Well we just use the ctr_img variable & jQuery’s :eq() selector.

The code for the left button is nearly the same. The only differences are we add to our left position thereby decreasing our left position. We place the last image before the first one, then reset the left position. Finally we scale the previous image to 100% instead of our next image as we are rotating the carousel the opposite way.

Infinite Carousel Gallery: Infinite Concept Explanation

Now for those that want to understand how the whole infinite part of the carousel works here is a infographics style explanation.

Here you can see how the images are laid out. It shows that when the page is loaded the last two images are actually at the front of the carousel. There are 7 images because that’s how many I used in my original example, but to show that it works with any number the demo shown at the start of this tutorial actually has 13 images.

Pressing right will push all the images to the left. The next image to the right will become the center image & to make sure it will be infinite the first image is moved to the end of the list. Every time you press the right button this happens, hence why you never run out of images to view.

Pressing left will push all the images to the right. The next image to the left will become the center image & again to make sure it will be infinite the last image is moved to the front of the list. Once again it does this on every press of the left button. This creates the infinite effect in the opposite direction.

Infinite Carousel Gallery: Conclusion

It’s been a long tutorial, but that is finally it. Hopefully I’ve explained how this all works to a point where it isn’t confusing. I built it, but even I still have moments where it confuses me simply due to the Maths involved (which I was never very good at).

Please remember that this is a tech demo again. Really though other than the scaling & box shadows in Internet Explorer 8, and below there isn’t anything that should cause older browsers many problems.

As always let me know if you have any comments, suggests, questions, or you just wanna say hey this is cool. 🙂 It’s always nice to hear from you guys & gals.


Author’s gravatar

Thanks for the great jQuery carousel. I have one idea for you. I need it too) When you click on right arrow auto sliding are rotating to right side, when you click on left arrow auto sliding are rotating to left side. By default, it rotates to the left side for example. It is difficult to do?
Sorry for my English. I am from Ukraine)

Author’s gravatar author

Hi Julia,

I’m sorry I’m not sure what you are asking?

Are you asking if it can be made into an auto slider? Someone a few comments back managed to get that working so you could check that out.

Author’s gravatar

[ed:- Thanks for sharing your alterations with us Dreau. A little bit of your code got stripped so I tried to put it back as best I could. Let me know if I’ve missed anything.]

Paul this is fantastic thank you!!

Just an add on if you want something extra. Change the onclick from img to ‘a’ so you can use the css a:hover for image change over the next and previous buttons. Just to let you know your over the button…

In the javascript…
Change the


of course you would do the same for

In the CSS…

do the same for the photos left.

and the HTML…
change the


Do the same for the photos right.

Now when you hover over the next or previous button the image will change.

Author’s gravatar author

Hi Dreau,

as I said in the little comment, thank you for sharing your changes. Let me know if I’ve guessed your code wrong as WP stripped a little bit of it.

Author’s gravatar

Nice work! thank you so much… this was a great help 😉

Author’s gravatar

Great stuff right here. Very nice.

Slightly disappointed by the fact that the link leads to a static image. Was expecting it to blow into a lightbox or something similar.

I am thinking of hooking this up with lightbox so the use does not have to leave the page when they click on an image.

Any ideas?

Author’s gravatar author

Hi Eddie,

I actually wanted to put a lightbox on when I first created it, but ended up forgetting.

I’ve added a lightbox to the demo so you can see what it would look like. I can’t find my full versions of all of the images so I’ve added another one to the demo (the 7th image to the right) so you can see the full sized lightbox working.

It’s pretty simple to add one in, but it depends on what lightbox you are using. With most though, if not all, you’d just want to target #photos_ul a to trigger the lightbox script.

Hope that helps, you can always view the source of the demo to see how I added the lightbox, if you have any questions please feel free to leave a comment, or drop me an email. 🙂

Author’s gravatar

Thank you for the speedy response as regards the lightbox. I am busy shamelessly copying and pasting your labours 🙂

Quick question on your lightbox, is there any particular reason why the lightbox does not allow the user to move to the next image without jumping out of the lighbox?

Author’s gravatar author

Hi Eddie,

No problem. 😉

Other than the fact you could then go through all the images without using the carousel, nope, lol.

If you want to be able to do that though feel free, you only need to add a rel attribute into all of the image tags & that should get the gallery system working. 😉

Author’s gravatar

and jcarousel ,it’s possible ???
thank you

Author’s gravatar author


I’m sorry. I’m not sure I know what you are asking?

Author’s gravatar

vertical it’s possible?

Author’s gravatar author

Hi Richard,

I don’t see why not, but you would have to alter the code to use the same premise but vertically. I would love to make it, but I just don’t have the spare time available. Sorry.

Author’s gravatar

Hi Paul !
nice work.
How to add a caption below?

Thanks .)

Author’s gravatar author


You could add the caption using the title attribute of the hyperlinks, or using the alt attribute of the image. Or even better, since this is HTML 5 you could use a data-* attribute to store it on the image.

Then it would be a case of adding an element into the code to show the caption, then some extra jQuery to load & swap the caption when the buttons are clicked.

I’d love to help out as I’m intrigued to know if it would work & look good, but I’m afraid I’m really packed with work at the moment & just don’t have the time to code it. 🙁

Author’s gravatar

Love this plugin! Excellent work.. 🙂 I however have a question about the minimum amount of images allowed for this to work.. I assumed it was three, but apparently not. Is there any way to make this function correctly when there are only three images present? Right now, it scrolls infinitely perfectly, but it doesn’t resize the middle photo to full scale. Thank you!

Author’s gravatar author

Hi Lexy,

It should indeed work. Are you by any chance in a browser that doesn’t support CSS based scaling?

Newer Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

I'll keep your WordPress site up-to-date and working to its best.

Find out more