Thumbnails Preview Slider with jQuery

In this tutorial we will show you how to create and use a thumbnails preview slider with jQuery. Since we got a lot of requests to show how to make […]

In this tutorial we will show you how to create and use a thumbnails preview slider with jQuery. Since we got a lot of requests to show how to make the preview slider work separately from the full image view, we decided to make a tutorial on how to use the little thumbnails preview part only.

Check out the Sweet Thumbnails Preview Gallery where me make use of the thumbnails slider idea.

The images are by talented tibchris and you can find them on his Flickr photostream:
tibchris’ photostream

So, let’s start with the markup.

Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.

The Markup

The HTML structure will be built up of a main container list that will hold the dot items and a special list item for the thumbnails. The special list item will have the class “ts_thumbnails” and it will be the element that holds the little window where we will see the thumbnails once we hover over a dot.

<ul class="ts_container">
	<li><a href="#">Image 1</a></li>
	<li><a href="#">Image 2</a></li>
	<li><a href="#">Image 3</a></li>
	<li><a href="#">Image 4</a></li>
	<li><a href="#">Image 5</a></li>
	<li><a href="#">Image 6</a></li>
	<li><a href="#">Image 7</a></li>
	<li><a href="#">Image 8</a></li>
	<li><a href="#">Image 9</a></li>
	<li><a href="#">Image 10</a></li>
	<li class="ts_thumbnails">
		<div class="ts_preview_wrapper">
			<!-- List with thumbnails/preview items -->
		</div>
		<span></span>
	</li>
</ul>

The empty span will be the little triangle that points to the current dot.
The thumbnails list which will be inside of the div with the class “ts_preview_wrapper” will have the following structure:

<ul class="ts_preview">
	<li><img src="images/thumbs1/1.jpg" alt="Thumb 1" /></li>
	<li><img src="images/thumbs1/2.jpg" alt="Thumb 2" /></li>
	<li><img src="images/thumbs1/3.jpg" alt="Thumb 3" /></li>
	<li><img src="images/thumbs1/4.jpg" alt="Thumb 4" /></li>
	<li><img src="images/thumbs1/5.jpg" alt="Thumb 5" /></li>
	<li><img src="images/thumbs1/6.jpg" alt="Thumb 6" /></li>
	<li><img src="images/thumbs1/7.jpg" alt="Thumb 7" /></li>
	<li><img src="images/thumbs1/8.jpg" alt="Thumb 8" /></li>
	<li><img src="images/thumbs1/9.jpg" alt="Thumb 9" /></li>
	<li><img src="images/thumbs1/10.jpg" alt="Thumb 10" /></li>
</ul>

Now, let’s take a look at the style.

The CSS

The main container list will be of relative positioning and its width will be the sum of the all the dots’ widths:

ul.ts_container{
	list-style:none;
	margin:0;
	padding:0;
	width:170px;
	margin:20px auto;
	position:relative;
	height:17px;
}

Like we will see later, the width of a dot is 11 plus a padding on each side of 3 pixels. This is just a general style for the main that we will we using in all three showcases. If you have more than 10 dots, you will need to adapt this value to fit all the items (same for the height).

The list items, i.e. the dots, will float left:

ul.ts_container li{
	float:left;
}

The dots itself will be a background image and we will indent the text so that we don’t see it:

ul.ts_container li a{
	display:block;
	text-indent:-9000px;
	width:11px;
	height:11px;
	outline:none;
	padding:0px 3px;
	background:transparent url(../images/sliderIcons/dot.png) no-repeat top center;
}

On hover, we will change the position of the background image so that we see the lower part of it:

ul.ts_container li a:hover,
ul.ts_container li.selected a{
	background-position:50% -11px;
}

The last list item which is our special thumbnails container will be of absolute positioning since we want to move it around. It’s initially not visible:

ul.ts_container li.ts_thumbnails{
	display:none;
	position:absolute;
}

The empty span will be our little triangle. We will set it’s position dynamically since it depends on the size of your thumbnails:

ul.ts_container li.ts_thumbnails span{
	background:transparent url(../images/sliderIcons/triangle.png) no-repeat top center;
	width:15px;
	height:6px;
	position:absolute;
}

Tip: If you feel generally uncomfortable with using empty elements in your HTML, simply add a meaningful text to it and set the text-indent to a very low value so that it’s not visible. Your HTML will be more readable and you can sleep better 🙂

The preview wrapper will have a white border and a nice box shadow. The dimensions are, again, set dynamically since they depend on the size of your thumbnails. The overflow should be hidden, because we will have a row of thumbnails in the list inside of this wrapper:

.ts_preview_wrapper{
	border:5px solid #fff;
	overflow:hidden;
	position:relative;
	-moz-box-shadow:0px 0px 5px #999;
	-webkit-box-shadow:0px 0px 5px #999;
	box-shadow:0px 0px 5px #999;
}

The list with all the thumbnails will be absolute, since we want to animate its left position in order to show the right thumbnail. The dimensions are calculated dynamically, for example, the width will be the sum of all thumbnails widths. But we will look into that when we define our JavaScript function.

ul.ts_preview{
	position:absolute;
	left:0px;
	top:0px;
	margin:0;
	padding:0;
	list-style-type:none;
}

The list items that hold the thumbnails will be floating left, so that they are stacked horizontally:

ul.ts_preview li{
	float:left;
}

The thumbnails need to be display block, to avoid any spacing in the li:

ul.ts_preview li img{
	display:block;
}

And that’s all the style! Let make some magic and go through one example.

The JavaScript

The main idea of this little thumbnail slider is to be able to use it with any (reasonable) size of thumbnails and to add certain effects to it. So, we will make a plugin which will look as follows:

(function($) {
	$.fn.thumbnailSlider = function(options) {
		var opts = $.extend({}, $.fn.thumbnailSlider.defaults, options);
		return this.each(function() {
			...
		});
	};
	$.fn.thumbnailSlider.defaults = {
		speed		: 100, //speed of each slide animation
		easing		: 'jswing', //easing effect for the slide animation
		thumb_width	: 75, //your photos width
		thumb_height: 75, //your photos height
		zoom		: false, //zoom animation for the thumbs
		zoomratio	: 1.3, //multiplicator for zoom (must be > 1)
		zoomspeed	: 15000, //speed of zoom animation
		onClick		: function(){return false;} //click callback
	};
})(jQuery);

Now let’s take a deeper look at the plugin functionality. First, we need to define some variables:

var $this 				= $(this),
	o 					= $.meta ? $.extend({}, opts, $pxs_container.data()) : opts;

var $ts_container		= $this.children('.ts_container'),
	$ts_thumbnails		= $ts_container.children('.ts_thumbnails'),
	$nav_elems			= $ts_container.children('li').not($ts_thumbnails),
	total_elems			= $nav_elems.length,
	$ts_preview_wrapper	= $ts_thumbnails.children('.ts_preview_wrapper'),
	$arrow				= $ts_thumbnails.children('span'),
	$ts_preview			= $ts_preview_wrapper.children('.ts_preview');

We also need to calculate some values that we need to set to certain elements. The “ts_thumbnails” container which is our little white frame that holds the list of thumbnails, will have a width composed of the thumbnail width and its border (which is 5 pixels on each side). The height will also contain the height of the little triangle span which is 6 pixels. The top will always be the same, a negative value since we need to “pull it up” to be above the dot list. The left value is calculated by getting the left position of the current dot and subtracting half of the thumbnails width. This will position it at the beginning of the respective dot, so we need to add half of the dot’s width in order really center it correctly above the dot:

/*
calculate sizes for $ts_thumbnails:
width 	-> width thumbnail + border (2*5)
height 	-> height thumbnail + border + triangle height(6)
top		-> -(height plus margin of 5)
left	-> leftDot - 0.5*width + 0.5*widthNavDot
	this will be set when hovering a dot,
	and the default value will correspond to the first nav dot
*/
var w_ts_thumbnails	= o.thumb_width + 2*5,
	h_ts_thumbnails	= o.thumb_height + 2*5 + 6,
	t_ts_thumbnails	= -(h_ts_thumbnails + 5),
	$first_nav		= $nav_elems.eq(0),
	l_ts_thumbnails	= $first_nav.position().left - 0.5*w_ts_thumbnails + 0.5*$first_nav.width();

Now we need to set all those values:

$ts_thumbnails.css({
	width	: w_ts_thumbnails + 'px',
	height	: h_ts_thumbnails + 'px',
	top		: t_ts_thumbnails + 'px',
	left	: l_ts_thumbnails + 'px'
});

Next step is to position the triangle correctly. For calculating the top of the triangle we need the height of the thumb plus its border. The left value will depend on the width of the thumbnail: we take the width plus the border and take half of that, and then we subtract half of the width of the triangle. This will center the little triangle:

/*
calculate the top and left for the triangle/tooltip
top		-> thumb height + border(2*5)
left	-> (thumb width + border)/2 -width/2
*/
var t_arrow	= o.thumb_height + 2*5,
	l_arrow	= (o.thumb_width + 2*5) / 2 - $arrow.width() / 2;
$arrow.css({
	left	: l_arrow + 'px',
	top		: t_arrow + 'px',
});

The list “ts_preview” that holds all the thumbnails, needs a width and we can calculate it by multiplying the width of a thumbnail with the number of total thumbnails:

/*
calculate the $ts_preview width -> thumb width times number of thumbs
*/
$ts_preview.css('width' , total_elems*o.thumb_width + 'px');

Then we set its width and also its height, which will simply be the height of a thumbnail:

$ts_preview_wrapper.css({
	width	: o.thumb_width + 'px',
	height	: o.thumb_height + 'px'
});

Now we will define what happens when we hover a navigation element i.e. a dot. We’ll get the index of the dot to know to which thumbnail item we need to slide to. Then we calculate the left value to which we want to slide the frame to, i.e. the “ts_thumbnails” list item. We also animate the list of thumbnails to the right position which we know because of the current index of the dot.

If the zoom option was chosen, we will increase the width and height of the thumbnail:

$nav_elems.bind('mouseenter',function(){
	var $nav_elem	= $(this),
		idx			= $nav_elem.index();

	/*
	calculate the new left
	for $ts_thumbnails
	*/
	var new_left	= $nav_elem.position().left - 0.5*w_ts_thumbnails + 0.5*$nav_elem.width();

	$ts_thumbnails.stop(true)
				  .show()
				  .animate({
					left	: new_left + 'px'
				  },o.speed,o.easing);				  

	/*
	animate the left of the $ts_preview to show the right thumb
	*/
	$ts_preview.stop(true)
			   .animate({
					left	: -idx*o.thumb_width + 'px'
			   },o.speed,o.easing);

	//zoom in the thumb image if zoom is true
	if(o.zoom && o.zoomratio > 1){
		var new_width	= o.zoomratio * o.thumb_width,
			new_height	= o.zoomratio * o.thumb_height;

		//increase the $ts_preview width in order to fit the zoomed image
		var ts_preview_w	= $ts_preview.width();
		$ts_preview.css('width' , (ts_preview_w - o.thumb_width + new_width)  + 'px');

		$ts_preview.children().eq(idx).find('img').stop().animate({
			width		: new_width + 'px',
			height		: new_height + 'px'
		},o.zoomspeed);
	}		

}).bind('mouseleave',function(){
	//if zoom set the width and height to defaults
	if(o.zoom && o.zoomratio > 1){
		var $nav_elem	= $(this),
			idx			= $nav_elem.index();
		$ts_preview.children().eq(idx).find('img').stop().css({
			width	: o.thumb_width + 'px',
			height	: o.thumb_height + 'px'
		});
	}

	$ts_thumbnails.stop(true)
				  .hide();

}).bind('click',function(){
	var $nav_elem	= $(this),
		idx			= $nav_elem.index();

	o.onClick(idx);
});

And that’s it! Now, let’s take a look at some examples!

Example


In the demo you will see four different examples, we will show you how to apply the last one. For that, we need to set the width and the height of the thumbnails and define some other parameters. We want the image to zoom in when we hover over the dot, so the following parameters are set:

$('#demo4').thumbnailSlider({
	thumb_width	: 174,
	thumb_height: 260,
	speed		: 200,
	zoom		: true,
	zoomspeed	: 10000,
	zoomratio	: 1.7
});

We hope you enjoyed the tutorial and find it useful!

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

Fresh news, inspo, code demos, and UI animations—zero fluff, all quality. Make your Mondays and Thursdays creative!

Feedback 29

Comments are closed.
  1. Sweet! I wonder why you prefer to call yourself “we”, while your bio says you are a freelancer.

  2. Hi Marry, it was beautiful, I like the thumbnail with zoom very much..

    This article is super easy to understand. I recommend all my team members working on Front-End designs to go through it, hence they have an idea, as what can be created with jQuery and CSS.

    Anyways, great tutorial. Twitted.

  3. WOW, still usually always great in result…hohoho
    and girls pict too…xixixixi :”>

  4. lol thanks a bunch! I sort of got it working, but I bet your code is cleaner than mines 🙂 So i’ll def take the time out to play around with this version

    Great as always

    -Sin

  5. guess that Website Design Surat made a “failed act”, don´t blame, with the sexy and beatifull things you do…

  6. This is the very reason I keep coming back to this site because you always come up with wonderful ways to solve problems or new innovative ways to display info and what not. Beautifully done!

  7. Thanks thanks thanks! I cant believe how much I ve learned since I start coming here.

  8. Mary, love this very much. Any simple hints to link the displayed images become clickable to specific urls?

  9. Thanks! very nice script and good point to read and learn..

    BTW
    I try with ie using my sequence of snaps .. but seems ie refuse to recognize the width..
    Any idea why?

  10. How can I change the script to fit more photos?
    I tried to change here …

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    …. by inserting additional lines, but to no avail. Can you help?
    thanks

  11. Thanks Mary Lou! Can you let us know what changes would need to be made for the images to show up in the same place no matter what dot is hovered over. As it is, they move from left to right slightly for the arrow that points to the dot to be centered. Thanks!

  12. This superb . I will use it in my next project but now I do need a simpler thumbnail slider like SlideItMoo
    can anyone here suggest?

    Best Regards

  13. Is there any way to put an arrow like this in picture in my page..pointing where i want, i dont care if it’s html,js,jq, or picture.. i just want to show me how to do it.. Thnx