jQuery Photo Slide Show with Slick Caption Tutorial Revisited

Written by Kevin Liew on 16 Dec 2009
190,653 Views • Tutorials


If you have been reading my website from the start you would have read this tutorial:

Simple jQuery Image Slide Show with Semi Transparent Caption

It's a very famous post because it has been showcased in several major web design blogs so many times and I received a lot of traffic from it. Thanks guys. I get a lot of comment and as I replied to those comments and do some quick fixes, I realized that this script has a caption bug and inefficient and not up to standard (oh well, that's the time when I was start picking up jQuery :)), so I have decided to do revisit to solve all those problems discovered by readers. I rewrote the html structure and modify the script.

Mission Objectives:

  • Restructure the HTML, more semantic
  • Fix the caption bug, it displays the next caption too fast
  • W3C standard compliant, using appropriate attribute to store title and description
  • Cross Browser - Chrome, Safari, IE6, 7, 8 and Firefox.

However, one thing though, it needs javascript, if your browser is javascript disabled, sorry, there is no graceful degradation for this script, it will just display the first item.



Yes, I'm using list this time :) This is how it should have been afterall. No more REL attribute, we wil be using TITLE Attribute to store the heading and ALT attribute to store the description. For the caption elements, it will be added using jQuery. So, this is it - a clean and simple HTML code.

<ul class="slideshow">
	<li class="show"><a href="#"><img data-src="images/s1.gif" width="450" height="200" title="Slide 1" alt="Short Description"/></a></li>
	<li><a href="#"><img data-src="images/s2.gif" width="450" height="200" title="Slide 2" alt="Short Description"/></a></li>
	<li><a href="#"><img data-src="images/s3.gif" width="450" height="200" title="Slide 3" alt="Short Description"/></a></li>

2. CSS

CSS code is rewritten completely. I guarantee it's cross browser compliant. They all look identical and it works great :) I did learn a lot of CSS technique through this blog. We all can improve our skills through tips, tricks, trials and errors. Read these posts to learn more about CSS:

body {

ul.slideshow {

ul.slideshow li {

ul.slideshow li.show {

ul img {

#slideshow-caption {

#slideshow-caption .slideshow-caption-container {
	padding:5px 10px;	

#slideshow-caption h3 {

#slideshow-caption p {
	margin:5px 0 0 0;

3. Javascript

We will going to use call back function to display caption. This will solve the "Caption Is Appearing Before The Next Slide Syndrome" :). Not too much of changes in javascript but I do added a feature though. On mouse over the slide will pause, and resume it back on mouse out. I think it's a good touch.

$(document).ready(function() {		
	//Execute the slideShow, set 4 seconds for each images


function slideShow(speed) {

	//append a LI item to the UL list for displaying caption
'); //Set the opacity of all images to 0 $('ul.slideshow li').css({opacity: 0.0}); //Get the first image and display it (set it to full opacity) $('ul.slideshow li:first').css({opacity: 1.0}).addClass('show'); //Get the caption of the first image from REL attribute and display it $('#slideshow-caption h3').html($('ul.slideshow li.show').find('img').attr('title')); $('#slideshow-caption p').html($('ul.slideshow li.show').find('img').attr('alt')); //Display the caption $('#slideshow-caption').css({opacity: 0.7, bottom:0}); //Call the gallery function to run the slideshow var timer = setInterval('gallery()',speed); //pause the slideshow on mouse over $('ul.slideshow').hover( function () { clearInterval(timer); }, function () { timer = setInterval('gallery()',speed); } ); } function gallery() { //if no IMGs have the show class, grab the first image var current = ($('ul.slideshow li.show')? $('ul.slideshow li.show') : $('#ul.slideshow li:first')); //trying to avoid speed issue if(current.queue('fx').length == 0) { //Get next image, if it reached the end of the slideshow, rotate it back to the first image var next = ((current.next().length) ? ((current.next().attr('id') == 'slideshow-caption')? $('ul.slideshow li:first') :current.next()) : $('ul.slideshow li:first')); //Get next image caption var title = next.find('img').attr('title'); var desc = next.find('img').attr('alt'); //Set the fade in effect for the next image, show class has higher z-index next.css({opacity: 0.0}).addClass('show').animate({opacity: 1.0}, 1000); //Hide the caption first, and then set and display the caption $('#slideshow-caption').slideToggle(300, function () { $('#slideshow-caption h3').html(title); $('#slideshow-caption p').html(desc); $('#slideshow-caption').slideToggle(500); }); //Hide the current image current.animate({opacity: 0.0}, 1000).removeClass('show'); } }


2010-09-10: Thanks to Rezzie who nailed the IE8 issue! :)

Updated the article and scripts, the link issue is fixed. :) Sorry for the delay.

Speed Issue

This is one of the issue that has been haunted me for a while, but thanks to Sam, one of our reader, he pointed out this would solve the issue, but with mixed result in IE.

Sam's solution, you need to add this:

$(window).focus(function () {
	timer = setInterval('gallery()', speed); 
$(window).blur(function () {

James Burnett's solution, you modify the gallery function():

function gallery() {
	var current = ($('ul.slideshow li.show')? $('ul.slideshow li.show') : $('#ul.slideshow li:first'));

	if(current.queue('fx').length == 0) {
		// grab next image and animate code in here

Also, did some research, found the reason why it's doing it: From jQuery Animate Documentation: Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.

Sorry guys, I don't have time to put all these together. Please let me know it works.

Randomize Slides

Simple yet effective solution from another reader - Blastos

Before the ending of function slideShow(), put this in:

//Generate a random number
var randNum = Math.floor(Math.random() * $('ul.slideshow li').length);

//Randomly pick up a slide
$('ul.slideshow li:eq('+randNum+')').addClass('show');

Caption doesn't appear for the first slide

I think it has to be the ommitted A tag for some users. Ammended the script, it should be fixed now.


I have made a lot of tutorials, and I think it's good to do a revisit to make it more efficient and solve some of the annoying bugs instead of quick fixes. So, yea, from now on, I will check my previous tutorials and rewrite them. :)

Like this tutorials? You can express your gratitude by visiting my sponsors on the sidebar, bookmark it and help me to spread this tutorial to our friends! :) Thanks!

Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

Phil 8 years ago
Is there anyway to link the alt text to another webpage?
Kevin Liew Admin 8 years ago
You can, but it won't look pretty. You actually can put HTML code in the ALT tag, but becareful with the quotes and double quotes.
Lou 8 years ago
Thank you for this script. A part of it is exactly what I've been looking for...the sliding-up Caption over the image.

I already have a gallery set with JQuery. Clicking a tumbnail brings the big image as an overlay.

Can I apply the part of the CAPTION sliding-up over the big image when it's called? All I found so far is captions with mouseover. (website to be compatible for iPads...no mouse)

If so, I'd be thankfull for any information on how to do it.
Thank you.
robert 8 years ago
Agree with all - very nice script. Could you tell me how to change the Javascript to make the slideshow play through just ONCE and then NOT return to the first image, please? The idea being that I want an image that will reveal itself in stages, but once complete, would remain on the page in full. Best wishes.
Kevin Liew Admin 8 years ago

Basically I made timer variable as global, and clear it once it reached the last slide in gallery function.
Brandon 8 years ago
I followed the instructions, but the slider isn't cycling through the images. Website is www.lostinidaho.me. Are there any steps I may have missed?
Joe 8 years ago
hi, awesome tutorial,

im having one issue, when i put it on my site it has made my lightbox not work, when you click on the image it just shows the image in another window instead of using the lightbox effect. Im not to sure why its doing this.

any help would be good.

thanks Joe

Kevin Liew Admin 8 years ago
Is your lightbox uses jQuery framework? Any console error?
Joe 8 years ago
yeah it is using js, no errors have came up that i have seen
Kevin Liew Admin 8 years ago
It's hard to see the issue. Do you have it online?
Jow 8 years ago
i dont actually, as it is still in development, is there some way i could send you the files, or i could work out a way to host the files then ill send you the link for you to download
Rob 8 years ago
I'm betting the function names are colliding with a function name in your lightbox. Probably gallery. try renaming the functions in the slideshow code and everywhere they are referenced.
Natspace 8 years ago
How would I make it stop after the last slide? Is it possible or not?
Thanx in advice!
Elisa 8 years ago
Sorry if somebody else asked the same question before.
Installed this slider. Everything works nicely, but now 'they' want a manual function to scroll through the slides as well as the automatic function
Is there a way to add previous and next button for manual option to this slider or do I have to install a different one?
Thanks so much!
Joshua Bambrick 8 years ago
My own take on the slideshow:

Has buttons to move to next or previous and circles at the top allow you to jump to a specific slide (and indicate the current slide).
ahmed 8 years ago
Very Very Very Thanks.........................................
CHSAdmin 8 years ago

Tried your take on the slider and have a few issues. 1) slideshowBox has more dots than there are slides? 2) prev arrow does not work on first slide? 3) i have four slides in the script but only three are appearing?

I have your version of the slideshow embedded on the News & Media page (for testing) at chscottenterprises.com.

Any help would be appreciated.
Robert 8 years ago
Hi, excellent tutorials. I've tried even the first slider tutorial, and now this one. However, what I want it to really do is to auto-resize to fit any display it is on, iPhone, iPad or Laptop, or full PC.
I can not find a way to make both the images and caption resize.
Sujay 8 years ago
Hi ,

I tried to run this slide show from database while I replaced the "first" to "last" and "next" to "Prev". All sildes worked but captions do not display. Can anybody help me with running the same above slide show from last to first please?
Nick W 8 years ago
Can anyone give guidance on adding a second caption please? I tried adding js code and css for "slideshow-caption2" but not made it work yet.
Chris 8 years ago
Hi Kevin, absolutely fantastic script that's worked a treat for the site I'm working on. However, instead of the slide toggle, is there a way to fade in the captions instead? That's what I'm really after. I'm awful with Jquery so I've no idea where to start unfortunately.
Brian Bauman 8 years ago
Using it on my site, I couldn't get the time issue to fix, so I changed a few lines. Line 49 I changed current.queue to $('ul.slideshow li').queue since it wasn't sure what current was, then I made the variables speed and timer global since its a small deployment.

Also had it clear and reset the Interval at the end of the gallery() function. Those fixes made it work perfectly for me.

You can see it under the about tab here: