jQuery Thumbnail Image Slider – CSS, JavaScript

Filed Under: jQuery

In continuation with the tutorial on “Creating your own Content-Slider with Pagination using jQuery/CSS“, today we’ll learn something eye catchy with our new article in “Sliders” series. This tutorial explains how to create jQuery thumbnail image slider and briefs about basic jQuery functions for adding styles to your elements dynamically. This will cover following topics in order:-

jQuery Thumbnail Image Slider

  1. What is a Thumbnail View? Why is it needed?
  2. Pre-requisites
  3. Foundation Stones – HTML5 ‘data’ attribute, CSS3 VSPs, handling CSS styling with jQuery i.e. using [addClass(), toggleClass(), removeClass(), data()] methods of jQuery.
  4. Implementing Thumbnail Photo Sliders –
    1. Basic Directory Structure.
    2. Layout of the Photo Slider.
    3. Understanding Pagination Styles.
    4. Codes for Photo Sliders with Thumbnail Pagination and Output.
  5. What’s next?

What’s Thumbnail View? Why is it needed?

Going by the definition of Thumbnail, a Thumbnail is a small representation of anything; in our case it’s an Image item. So to be able to view these thumbnails enable us to navigate to more relevant slides.

In our slider, we will be replacing those simple text based pagination index with these thumbnail views of the images by using resized images. This makes our slider more expressive and effective. We can also create a Pop-up image gallery based on this thumbnail concept.

Pre-requisites

This article assumes readers have basic knowledge about what are a webpage, HTML basic tags, few CSS properties and know-how of JavaScript. You can refer to the www.w3schools.com website for these topics.

Basic jQuery functions used in this article are explained in the next heading ‘Foundation Stones’. Those who are familiar with these stuffs can directly start with the “Implementing Thumbnail Photo Sliders” section.

Foundation Stones

Let’s clear some concepts, which may be new to the readers. Starting with –

  1. HTML5 ‘data-*’ attribute

    ‘data-*’ is a custom global attribute introduced newly in HTML5 and can be used with any HTML element to embed custom data to any element. It uses following syntax;

    
    <element data-*="string-value">
    

    It can be used to give more engaging user experience and also avoid usage of Ajax and back-end data queries. For example;

    
    <li data-index="1"><img src='images/one.jpg'></li>
    <li data-index="2"><img src='images/two.jpg'></li>
    <li data-index="3"><img src='images/three.jpg'></li>
    

    So in javascript code we can access these elements individually using data() method of jQuery explained below.

  2. CSS3 Vendor-Specific Prefixes (VSPs)

    ‘Vendors’ are Browser-Makers who define the response of each CSS properties for their browsers. When those properties are new, it may be possible that they are not supported by all the browsers(because their implementations are not done yet!). Those makers who have done their implementation use Vendor-Specific Prefixes to test their Browser for Compatibility of properties.

    In short, to avoid Browser Compatibility issues in later stage, we should use VSPs for some new CSS properties until these properties become W3C standards(i.e. when they are supported by most of the browsers).

    Their syntax is –

    ‘-‘ + vendor specific identifier + ‘-‘ + meaningful name

    For example;

    
    border:2px solid rgb(6, 61, 92);
    /*border-radius*/
    -webkit-border-radius:5px 5px 10px 10px;
    -moz-border-radius:5px 5px 10px 10px;
    border-radius:5px 5px 10px 10px;
    

    There are different VSPs like -webkit-(for safari and chrome), -moz-(for firefox),  -o-(for Opera), -ms-(for Internet Explorer), -khtml-(for Konqueror  browser).

  3. jQuery Methods
    1. data() Method
      • This method sets/gets the value of data attribute(new in HTML5) for first element from a set of matched HTML elements.
      • It stores the data associated with the matched element.
      • It can retrieve values either set by data() method, or from data-* attribute of HTML5.
        1. Syntax for setting data:- [ .data( key, value ) or .data(obj) ]

          Here the key can be any valid identifier. Value can be any type of value, viz. numerals, strings, array of Key-Value Pairs or any object of key-value pairs type of data.

          For example;

          
          $( "body" ).data( "country", "India" );
          
          $( "body" ).data( "result", { sub: "Maths", score: 70 } );
          
          $( "body" ).data( { arr: [ 1, 2, 3 ] } ); // Passing object as parameter to data() method.
          
        2. Syntax for getting data:- [ .data(key) ]

          Here ‘key’ is the data-attribute’s name. E.g. in ‘data-country’, country specified the key for data attribute.

          For above setter methods following can be used to extract the values.

          
          $( "body" ).data( "country" ); // India
          
          $( "body" ).data(); // Retrieve all data-attribute values.
          

          Example Using HTML5 data-* attribute

          HTML code will be:-

          <div data-role=”page” data-last-value=”43″ data-hidden=”true” data-options='{“name”:”John”}’></div>

          Corresponding JavaScript code will be:-

          
          $( "div" ).data( "role" ) // "page";
          
          $( "div" ).data( "lastValue" ) // 43;
          
          $( "div" ).data( "hidden" ) // true;
          
          $( "div" ).data( "options" ).name // "John";
          
    2. addClass() Method
      • This methods dynamically adds the specified class(es) to set of matched elements.
      • Note that it doesn’t checks for redundancy of classes and simply appends to the existing set of classes.
      • It can be used for dynamically changing the styles of any HTML element.
      • Mostly used in combination with removeClass() method explained below.

      Syntax for adding class:- [ .addClass( className ) or .addClass( function ) ]

      • Here the ‘function’ can be any function returning the class(es).
      • It accepts ‘index’ of current element and ‘string’ of current classes on that element.

      For Example;

      
      $( "p" ).addClass( "myClass yourClass" );
      
      $( "ul li" ).addClass(function( index ) {
      	return "item-" + index;
      	});
      
    3. removeClass() Method
      • This method removes all the matched classes passed as a parameter to this method from a set of Matched elements.
      • If no parameter is specified, then all the classes will be removed. Be cautious!!
      • Often used in combination with addClass() method.

      Syntax for removing class:-            [ .removeClass( className ) or .removeClass( function ) ]

      Here the ‘function’ can be any function returning the class(es).

      For example;

      
      $( "p" ).removeClass( "myClass yourClass" )
      
      $( "li:last" ).removeClass(function() {
      	return $( this ).prev().attr( "class" );
      });
      
      $( "p" ).removeClass( "myClass noClass" ).addClass( "yourClass" );
      
    4. toggleClass() Method
      • It toggles(adds or removes) class(es) from a set of Matched elements.
      • Good alternative for “remove() then add()” method.

      Syntax for toggling the class(es):- [ .toggleClass( className ) or .toggleClass( className, switch ) ]

      Here ‘className’ refers to specified class(es) and optional ‘switch’ is a boolean parameter for specifying whether to add(true) or remove(false) the class from the set of matched elements.

      For example;

      Initial HTML Code will be:-

      
      <div class="tumble">Some text.</div>
      

      After applying, $( “div.tumble” ).toggleClass( “bounce” ); we get,

      
      <div class="tumble bounce">Some text.</div>
      

      After applying again, $( “div.tumble” ).toggleClass( “bounce” ); we get,

      
      <div class="tumble">Some text.</div>
      

Implementing Thumbnail Photo Sliders

Now with some basic background JavaScript methods and HTML, we can proceed with the slider implementation. Just follow the following guidelines-

  1. Creating Directory Structure

    Let’s organize different resources among folders in our Root directory.

    • ‘ThumbnailPhotoSlider’ is our Root folder having HTML files with other sub-folders.
    • ‘scripts’ folder contains the Javascript libraries such as JQuery and some other script files.
    • ‘styles’ folder contains CSS files defining styles of different HTML tags.
    • ‘images’ folder contains images in two groups as ‘bigimg’ for storing slider images and ‘thumbimg’ for storing resized smaller images.

    jquery thumbnail image slider gallery directories

  2. Creating Layout of Image Slider

    The layout of the slider is as shown in the figure in the Creating your own Content-Slider with Pagination using jQuery/CSS article.

  3. Understanding Pagination Styles

    It’s very important to understand how we have laid out the Pagination controls and, what happens when more images are added?

    Our design automatically handles this case by having a fluid representation, i.e. when the thumbnails overflow the slider region horizontally it is wrapped in the middle using ‘text-align’ CSS property (see the CSS code). The layout of this Pagination is shown as below;

    jquery thumbnail gallery layout
    Explanation of jQuery “Prototype Functions” in ‘js’: –

    Those who have followed the slider’s layout, can now try to understand the Prototype Function in jQuery from our Previous Tutorial. After learning what are prototype functions (transition and setCurrentPos), let’s start with the Implementation of our Thumbnail Photo Slider.

  4. The Thumbnail Photo Slider Implementation( Codes )

    If you have understood the layout of Pagination Controls in our previous tutorials, it’s quite easy to understand how we convert the same pagination with Thumbnail view of the Images.

    Instead of creating the Pagination dynamically in ‘thumbnailSliderScript.js’ file, we’ll add a list of image items in our HTML code and from JS file, we’ll assign a ‘data’ attribute named ‘pgno’ to each such image item, dynamically.

    Also in our ‘thumbnailSliderScript.js’ file, we’re using two methods named removeClass(), and toggleClass(), for dynamically changing the CSS property of the current pagination image and rest other thumbnails.

    The ThumbnailSlider.html file has structural elements along with scripts related to creation of the object for our slider. Observe how each of the slide content is enlisted as the unordered list elements. Two files thumbnailStyle.css and thumbnailSliderScript.js contain styles and methods for controlling the slider motion, direction and also for styling the Pagination thumbnail. You would also need reference to JQuery Library i.e. https://code.jquery.com/jquery-2.1.0.js which you can download and save in the folder ‘scripts’.

    Codes for all these files are as shown below.

    ThumbnailSlider.html

    
    <!Doctype html>
    <html>
    	<head>
    		<title>Thumbnail Slider</title>
    		<link rel="stylesheet" href="styles/thumbnailStyle.css">		
    	</head>
    	<body>
    		<!-- Container for Slider, Navigation and Pagination Controls -->
    		<div class="gallery-container">			
    			<div class="gallery">
    				<h2>Thumbnail Slider</h2>
    				<!-- The actual moving Slider -->
    				<div class="slider">
    					<ul>
    						<li>
    							<img src="images/bigimg/bigimg1.jpg" class="slides" alt="Image1">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg2.jpg" class="slides" alt="Image2">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg3.jpg" class="slides" alt="Image3">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg4.jpg" class="slides" alt="Image4">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg5.jpg" class="slides" alt="Image5">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg6.jpg" class="slides" alt="Image6">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg7.jpg" class="slides" alt="Image7">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg8.jpg" class="slides" alt="Image8">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg9.jpg" class="slides" alt="Image9">
    						</li>
    						
    						<li>
    							<img src="images/bigimg/bigimg10.jpg" class="slides" alt="Image10">
    						</li>
    					</ul>
    				</div>
    				
    				<!-- Navigation Button Controls -->
    				
    				<div class="slider-nav">
    					<button class="backbtn" data-dir="prev">Previous</button>
    					<button class="nextbtn" data-dir="next" style="float:right;">Next</button>
    				</div>					
    			</div>
    			<!-- Pagination Controls -->
    			<div class="slider-pagi">					
    				<div class="pagi-container">
    					<!-- Here Thumbnail Paginations will be dynamically assigned a Page ID(i.e. 'pgno'Starting with 0) -->
    					<ul>
    						<li><a href="#"><img src="images/thumbimg/thumbimg1.jpg" alt="Image1"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg2.jpg" alt="Image2"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg3.jpg" alt="Image3"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg4.jpg" alt="Image4"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg5.jpg" alt="Image5"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg6.jpg" alt="Image6"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg7.jpg" alt="Image7"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg8.jpg" alt="Image8"/></a></li>
    						<li><a href="#"><img src="images/thumbimg/thumbimg9.jpg" alt="Image9"/></a></li>						
    						<li><a href="#"><img src="images/thumbimg/thumbimg10.jpg" alt="Image10"/></a></li>						
    					</ul>
    				</div>
    			</div>
    		</div>
    		
    		<!-- Loading JavaScript Codes. -->
    		<script src="scripts/jquery-2.1.0.js"></script>
    		<script src="scripts/thumbnailSliderScript.js"></script>
    		<script>
    			// 
    			
    			jQuery(document).ready(function ($) {
    				
    				// creating a container variable to hold the 'UL' element. It uses method chaining.
    				var container=$('div.slider')
    											.css('overflow','hidden')
    											.children('ul');
    				
    				// creating pagination variable which holds the 'UL' element.
    				var pagicontainer=$('div.pagi-container').children('ul');
    				
    				/* 
    				On the event of mouse-hover, 
    					i) Change the visibility of Button Controls.
    					ii) SET/RESET the "intv" variable to switch between AutoSlider and Stop mode.
    				*/
    				$('.gallery').hover(function( e ){
    					$('.slider-nav').toggle();
    					return e.type=='mouseenter'?clearInterval(intv):autoSlider();
    				});
    				
    				// Creating the 'slider' instance which will set initial parameters for the Slider.
    				var sliderobj= new slider(container,pagicontainer,$('.slider-nav'));
    				/*
    				This will trigger the 'setCurrentPos' and 'transition' methods on click of any button
    				 "data-dir" attribute associated with the button will determine the direction of sliding.
    				*/
    				sliderobj.nav.find('button').on('click', function(){
    					sliderobj.setCurrentPos($(this).data('dir'));
    					sliderobj.transition();
    				});
    				
    				/*
    				This will trigger the 'setCurrentPos' and 'transition' methods on click of any Pagination Thumbnail icon.
    				 "data-pgno" attribute associated with the Thumbnail icons will determine the value of 'current' variable.
    				*/
    				sliderobj.pagicontainer.find('li a').on('click', function(){
    					sliderobj.setCurrentPos($(this).data('pgno'));
    					sliderobj.transition();					
    				});
    				
    				autoSlider(); // Calling autoSlider() method on Page Load.
    				
    				/* 
    				This function will initialize the interval variable which will cause execution of the inner function after every 3 seconds automatically.
    				*/
    				function autoSlider()
    				{
    					return intv = setInterval(function(){
    						sliderobj.setCurrentPos('next');
    						sliderobj.transition();
    					}, 3000);
    				}
    				
    			});
    		</script>
    	</body>
    </html>
    

    thumbnailStyle.css

    
    *
    {
    	margin:0;
    	padding:0;
    }
    
    /* ============================== This is for Overall Styling of the Content Gallery. */
    .gallery-container
    {
    	border:2px solid rgb(6, 61, 92);
    	/*border-radius*/
    	-webkit-border-radius:5px 5px 10px 10px;
    	-moz-border-radius:5px 5px 10px 10px;
    	border-radius:5px 5px 10px 10px;
    	margin:10px auto;
    	padding:0px;
    	display:table;
    }
    
    .gallery
    {
    	width:640px;
    	height:370px;
    	background:#999;
    	/*border:2px solid green;*/
    }
    
    .gallery h2
    {
    	font-size: 20px;
    	background: #C5BBBB;	
    }
    
    .slider
    {
    	overflow:scroll;
    }
    .slider ul
    {
    	width:100000px;
    	list-style:none;
    	margin-left:0px;
    }
    .slider li
    {
    	float:left;
    }
    
    /* ============================== This is for Navigation Buttons Styling. */
    .slider-nav
    {
    	display:none; /* This is important to hide the buttons if jQuery is Not supported. */
    	margin-top: -10em;
    	cursor: pointer;
    }
    
    .backbtn
    {
    	position:relative;
    	opacity:0.5;
    }
    
    .nextbtn
    {
    	position:relative;
    	opacity:0.5;
    }
    
    /* ============================== This is for Pagination Styling. */
    .slider-pagi
    {
    	/*border:2px solid red;*/
    	text-align:center; /* Important : Keeps the Pagination in the center. */
    	width:640px;
    }
    
    .pagi-container
    {
    	/*border: 2px solid cyan;*/
    	padding: 5px;
    	display: inline-block;  /* This is a good alternative for inline-flex and supports most of the browsers. */
    	/* display: inline-flex; */ /* This is important to remove the extra vertical spaces  between 'UL' and 'pagi-container' */
    }
    
    .pagi-container > ul
    {
    	padding:2px;
    	/*border:1px solid black;*/
    	display: inline-block;	
    }
    
    .pagi-container > ul li
    {
    	/* float:left; */ /* Instead write "display:inline-block" Property to set the pagi-elements in center. */
    	list-style:none;
    	padding:0px; /* Setting padding as zero will increase clickable region of child('a' Anchor Element) of LI element */
    	border:1px solid #aaa;
    	margin: 0px auto;
    	margin-bottom:5px;
    	display:inline-block;
    	background: radial-gradient(rgba(255, 255, 255, 0.8) 50%, rgba(180,180,180,0.8));		
    }
    
    .pagi-container > ul li:hover
    {
    	background: radial-gradient(rgba(220, 220, 220, 0.3), rgba(180,180,180,0.8) 95%);
    }
    
    .pagi-container > ul li a
    {
    	display:inline-block;
    	padding:5px; /* This is important to Increase the Clickable Region of the anchor Elements */
    	text-decoration:none;
    	color:rgb(100,100,100);	
    	/* display:inline-flex; */
    }
    
    .pagi-container > ul li a img:hover
    {
    	opacity:1.0;
    }
    
    .img-normal
    {
    	opacity:0.5;
    	vertical-align:bottom; /* Very Important to Vertically Centre the Thumbnail and removing the bottom space between and Image and the container Anchor Tag. */
    }
    
    .img-selected
    {
    	opacity:1.0;
    }
    
    .pagi-selected
    {
    	/*box-shadow*/
    	-webkit-box-shadow:0 0 15px #000;
    	-moz-box-shadow:0 0 15px #000;
    	box-shadow:0 0 15px #000;
    	opacity:1.0;
    }
    
    
    /* ============================== This is for Styling Each of the Content Slides */
    .slides
    {
    	width:640px; /* This width is reduced to compensate the padding on left and right */
    	height:345px; /* This height is reduced to compensate the padding on top and bottom */	
    	background-color:rgb(198,185,221);		
    }
    

    thumbnailSliderScript.js

    
    /*
    This method will initialize each slider instance.
    Parameter are: -
    ------------------
    1) container -> div.slider ul
    2) pagicontainer -> div.pagi-container ul
    3) nav -> #slider-nav
    */
    function slider(container, pagicontainer, nav){
    	this.container=container;
    	this.pagicontainer=pagicontainer;
    	this.nav=nav.hide(); // This will assign 'nav' from parameters to 'nav' of current slider instance. It uses method chaining.
    	this.imgs=this.container.find('.slides'); // Returns jQuery object containing all matched elements.
        this.width=this.imgs[0].width; // Each image is Identical in Dimension.
    	console.log('Value of width is : '+this.width);
    	this.imgLen=this.imgs.length; // Returns the total number of sliding elements.
    	console.log("Total no. of Items in the list are : "+this.imgLen);
    	// Here we will add the "data-pgno" attribute to the Thumbnail Pagination.
    	cnt=0;
    	this.liArr = $(pagicontainer).find('li');// Returns jQuery object containing all matched LI elements of Pagination Thumbnails.
    	this.liArr.each(function()
    	{
            $anchor=$(this).find('a');
    		$anchor.data('pgno',cnt);
    		cnt++;
        });
    	this.current=0; // Initialize the "current" counter.
    	// Apply initial Styling to all Pagination Thumbnail Image Elements.
    	this.pagicontainer.find('li a img').toggleClass('img-normal');
    	// Apply CSS to "First" pagination element in the list.
    	this.pagicontainer.find('li:nth-child(1) a').toggleClass("pagi-selected");	
    	this.pagicontainer.find('li:nth-child(1) a img').toggleClass("img-selected");
    }
    
    // This method will apply the needed animation and displacement.
    
    slider.prototype.transition=function(coords){
    	this.container.animate({
    		'margin-left': coords || -(this.current*this.width) // First element is multiplied by Zero.
    	},500);
    	// Remove CSS from Rest other pagination element in the list.
    	this.pagicontainer.find('li a').removeClass("pagi-selected");
    	this.pagicontainer.find('li a img').removeClass("img-selected");
    	
    	// Apply CSS to current pagination element in the list.
    	this.pagicontainer.find("li:nth-child("+(this.current+1)+") a").toggleClass("pagi-selected");
    	this.pagicontainer.find("li:nth-child("+(this.current+1)+") a img").toggleClass("img-selected");
    	
    	
    };
    
    // This method will set the "current" counter to next position.
    /*
    Parameters are:-
    ---------------
    1) dir -> It can be either 'prev' or 'next' or else a number denoting slides.
    */
    slider.prototype.setCurrentPos=function(dir){
    	var pos=this.current;
    	console.log('Value of this.value is : '+dir);
    	if(isNaN(dir))
    	{
    		pos+= ~~(dir=='next') || -1; // You can use alternate "Math.floor()" method instead of double tilde (~~) operator.
    		this.current=(pos<0)?this.imgLen-1: pos%(this.imgLen);
    	}
    	else
    		this.current=Number(dir);
    	console.log(this.current);
    	
    };
    

    The source codes have comments wherever it is needed. In case of specific doubt you can ask me directly by commenting.

jQuery Thumbnail Image Slider Output

jQuery Thumbnail Image Gallery, jQuery thumbnail image slider

NOTE: If you are using Chrome browser and want to debug your scripts, you can Press [F12] key and click on ‘Console’ tab to see how ‘current’ counter is changing on click of a button.

You can see this slider in action by visiting below demo page.

What’s next?

Having done with these pure jQuery sliders, in the next article I’d be presenting another way of creating sliders using CSS3 transition and jQuery. Get ready for some cool image sliders. Happy learning!

Comments

  1. anil says:

    Awesome Post

Leave a Reply

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

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages