How to Create a Showcase with jQuery

Tweet

Showcases are a great way to show your visitors your latest addition to your portfolio or to present the latest product or article. Many sites use this technique to cram information into an area so that your visitors do not miss your message.

This tutorial will show you how to create such a showcase by utilising jQuery.

jQuery makes animation easy. This tutorial will guide you through the setting up of your HTML, CSS and the associated jQuery code to create the showcase.

The HTML

The viewport div is our window to the content that you wish to display to the user. We’ll use CSS later to ensure the viewport only displays the content you want. Inside the div, we will be enclosing two further divs; one for the sections and another for the labels which will pop up when the viewport scrolls into view. Both of these will be inside another div: scrollable which will be the element we use to scroll all the content within it into view. The sections div will contain four further divs which will represent our sections and the labels div will contain another four divs to represent our labels. Lastly, we’ll create a row of simple buttons so we can elect to scroll a certain section into view.

	<div id="viewport"> 
 
		<div id="scrollable"> 
 
			<div id="sections"> 
 
				<div id="section1" class="section"> 
				<h1>Uluru</h1> 
				</div> 
 
				<div id="section2" class="section"> 
				<h1>The Eiffel Tower</h1> 
				</div> 
 
				<div id="section3" class="section"> 
				<h1>Empire State Building</h1> 
				</div> 
 
				<div id="section4" class="section"> 
				<h1>The Great Wall of China</h1> 
				</div> 
 
			</div> 
 
			<div id="label"> 
 
				<div class="label"> 
				<p>Also known as Ayre's rock</p> 
				</div> 
 
				<div class="label"> 
				<p>In the world's most romantic city</p> 
				</div> 
 
				<div class="label"> 
				<p>Site of the last hour of King Kong's life</p> 
				</div> 
 
				<div class="label"> 
				<p>This can be seen from space</p> 
				</div> 
 
			</div> 
		</div> 
	</div> 
 
	<div id="menu"> 
 
	<div id="scroll1" class="button"></div> 
	<div id="scroll2" class="button"></div> 
	<div id="scroll3" class="button"></div> 
	<div id="scroll4" class="button"></div> 
 
	</div>

The CSS

We’ll start with the viewport itself. We want to set the dimensions of the viewport, ensure that any content within it does not flow out and we’ll add a thick 5px solid border.

#viewport 
{ 
	overflow:hidden; 
	border:5px solid; 
	height:300px; 
	width:600px; 
}

The sections and labels divs are very similar. The width will be determined by the number of sections you want to have multiplied by the width of each section. In this example, our sections are 600px wide and we will be using four of them so the width of the #content and #label divs will be 2400px (4 x 600px). The width and height are all we need to style the sections div.

#sections
{ 
	width:2400px; 
	height:300px; 
} 

The label div is slightly different since we require it to slide out of view when we click on a button and it does not need to be 300px as this would obscure the entire viewport when it came into view. We’ll set this to 100px high. We also need to ensure that the label appears when the page is first loaded, so we set the bottom property to 100px so that it appears 100px above the bottom of the div in which it resides. We also require setting the position to relative so we can use the bottom property.

#label 
{ 
	position:relative; 
	width:2400px; 
	height:100px; 
	bottom:100px; 
}

Both contents and labels are wrapped in another div identified as scrollable which will be the element we use to move all the content within it. This needs to be set to the dimensions of the content div as this contains all that will be viewable in the viewport. We need to set the position relative since we will be taking advantage of the left property via jQuery to scroll the content into view.
We’ll look at the individual section divs now to style them for our purposes. Each div classed as section needs to float left of each other otherwise the content will flow out of the containing div and onto the next row. We need these to be next to each other so that when we alter the left position of the #scrollable, the relevant section will come into view. Our sections will be 600px wide by 300px hight wide but we’ll add some padding of 10px so everything isn’t flush to the sides of the viewport. Our height and width will need to be reduced by 20px to cater for this.

.section 
{ 
	float:left; 
	padding:10px; 
	width:580px; 
	height:280px; 
}

The individual label divs will be 600px wide and 100px high with a 10px padding. We also need to float these left so that they appear next to each other and don’t stack on top of each other. We’ll also set the background colour of the label to grey and the colour of the text to white.

.label 
{ 
	float:left; 
	padding:10px; 
	height:80px; 
	width:580px; 
	background-color:#777; 
	color:white; 
}

We’ll add some images to the background. I used some images from wikimedia commons, scaled them down to 600px by 300px and set them as background images.

#section1 
{ 
	background-image:url('../image/uluru.jpg'); 
} 
 
#section2 
{ 
	background-image:url('../image/eiffeltower.jpg'); 
} 
 
#section3 
{ 
	background-image:url('../image/empirestate.jpg'); 
} 
 
#section4 
{ 
	background-image:url('../image/greatwall.jpg'); 
}

The last bit of styling we need to do is the menu section which will allow us to scroll through to the various sections. You can do this in any manner you want but for this example, we’ll just use some simple divs wich will be 30px by 30px, have a background colour of grey and be spaced 5px from each other by setting a margin of 5px. These buttons will all be wrapped in another div which we don’t need to style but contains all of our buttons.

.button 
{ 
	height:30px; 
	width:30px; 
	background-color:#777; 
	float:left; 
	margin:5px; 
}

So that is all the css done and now we’re ready to get our hands dirty with jQuery.

The jQuery

Queuing Events

We’ll start first by examining what it is our showcase “widget” will do. When we click on one of our buttons, we want our label to drop down out of view, the new section to come into view and then the label to pop back up again. We’ll be scrolling the scrollable div so we only need to be concerned with scrolling that – everything within it will be dragged along.

So the order of events is:

  1. hide the label
  2. scroll the viewport
  3. show the label

There are a number of ways to implement this but we’ll cover the queue function that jQuery supplies. Queuing is the principle of adding events to an object and then dequeuing them or executing them. We’ll create a function which queues three functions to hide the label, scroll the viewport and then show the label. Queuing an event requires attaching the event to an object in the DOM. You can create custom queues or, if not specified, you can use the default queue (called ‘fx’). Once you queue an event in fx, the first function will execute. However, the next function needs to be explicitly called to execute.

The main function navigate will set up the queued events. We will also add a function to clear the queue so that events don’t back up which would result in the queue getting larger and taking longer to complete. clearQueue(), if supplied with no arguments, will clear the events on the default fx queue.

	function navigate(position) 
	{ 
		$('#scrollable').clearQueue(); 
 
		$('#scrollable').queue(hideLabel); 
		$('#scrollable').queue(scroll(position)); 
		$('#scrollable').queue(showLabel); 
	}

Animating the Elements

We’ll define these functions next by using the animate() method and make use of a callback to dequeue the next event.

To hide the label, we need to move the bottom position of the label to 0px making it disappear from the viewport and we’ll nominate that this takes a quarter of a second or 250 milliseconds. We also need to ensure that the next event in the queue executes and so we create an inline function dequeueing the next event.

	function hideLabel() 
	{ 
		$('#label').animate( 
			{bottom:'0px'}, 
			250, 
			null, 
			function() 
			{ 
				$('#scrollable').dequeue(); 
			}); 
	}

Next, we need to scroll the scrollable div to the relevant position. Since each section is 600px we need to move the div to the left 600px for every section. To show the first section in the viewport, the left property needs to be 0px which is the default state when the page is loaded, to view the second section, we need to set left to -600px, the third; -1200px and so on. This transition will take 500 milliseconds or half a second. We also need to dequeue the next event in the queue so again we create an anonymous function to do this:

	function scroll(position) 
	{ 
		position = position + "px"; 
 
		$('#scrollable').animate( 
			{left:position}, 
			500, 
			null, 
			function() 
			{ 
				$('#scrollable').dequeue(); 
			}); 
	}

The last function needs to show the label again, so we set the bottom css property back to 100px and ensure this takes place over 250 milliseconds. We don’t need to trigger the next event in the queue as this is the last in the sequence.

	function showLabel() 
	{ 
		$('#label').animate( 
			{bottom:'100px'}, 
			250); 
	}

Binding the Events

The next thing we need to do is attach the navigate event to relevant elements on the page. In our case this would be the four buttons we defined earlier. The best way to attach these events is to do it through jQuery. The document needs to be fully loaded before we do this so we use the ready() function to wrap the code in.

We use jQuery’s click function to instantiate an anonymous function which in turn triggers the navigate function with an appropriate value for position.

$(document).ready(function() 
		{ 
 
			$('#scroll1').click(function() 
				{ 
					navigate(0); 
				} 
			); 
 
			$('#scroll2').click(function() 
				{ 
					navigate('-600'); 
				} 
			); 
 
			$('#scroll3').click(function() 
				{ 
					navigate('-1200'); 
				} 
			); 
 
			$('#scroll4').click(function() 
				{ 
					navigate('-1800'); 
				} 
			);
		}
	);

So that is all that is required to create the scrolling showcase “widget” but we’ll just add a few more lines of jQuery to add some opacity to the label and make it fade in when the mouse is over it and fade out when the mouse is moved out of it. This code can simply be added to the ready() function ensuring it isn’t executed until the document is fully loaded. We’ll bind the event since, as you will see later, we will need to unbind it in certain circumstances. The two functions to fade in and fade out are defined as:

	function fadeOut() 
	{ 
		$('#label').stop().fadeTo(250,0.7); 
	} 
 
	function fadeIn() 
	{ 
		$('#label').stop().fadeTo(250,1); 
	}

We’ll also add a piece of code to set the opacity initially to 0.7. This is where jQuery really excels. There are many inconsistencies between browsers with the css opacity property but we don’t have to worry about that. All we need to do is specify the W3C standard opacity property. jQuery does the rest. Again, this can be added to the ready() function.

			$('#label').css("opacity", "0.7");

Tidying Up

You’ll notice that when using the button to select your new section, if you move your mouse to the label quickly, the animation stops suddenly. This is because we have bound an event to the label element and used stop() to stop the events from queuing up and making the UI unusable. We can detach this event and reattach it once the scrolling has been completed so as not to cause disruption. In our navigate function, we will unbind the event before creating the queue:

	function navigate(position) 
	{ 
		$('.label').unbind('mouseover', fadeIn); 
		$('.label').unbind('mouseout', fadeOut); 
 
		$('#scrollable').clearQueue(); 
 
		$('#scrollable').queue(hideLabel); 
		$('#scrollable').queue(scroll(position)); 
		$('#scrollable').queue(showLabel); 
	}

Now that the event is detached, the animation won’t be stopped should our mouse enter the label area. We’ll need to reattach this once all the animation is complete. A sensible place to do this would be to call an anonymous callback function in the showLabel() function since this is the last in the queue and will only execute when this is complete.

	function showLabel() 
	{ 
		$('#label').animate( 
			{bottom:'100px'}, 
			250, 
			function() 
			{ 
				$('.label').bind('mouseover', fadeIn); 
				$('.label').bind('mouseout', fadeOut); 
			}); 
	}

One final thing we should do is to ensure that no animation is called if we are attempting to select a section that we are already on. We can do this by string a variable which indicates which page we’re on and then testing this in the navigate() function to determine whether we should execute the transition. We’ll create a variable which is outside the scope of any function so anywhere can have access to it called currentPage and set this to 1 to begin with. We’ll alter the navigate() function to take a second argument; page which will notify the function which section is being called. This value can be tested against currentPage to see if the animation should occur. If the current page is not being called, we can animate and then set currentPage to be the page that was called. The navigate() function should be updated to this (note that we have declared the currentPage variable just above this):

	var currentPage;

	function navigate(position, page) 
	{ 
		if(page != currentPage) 
		{ 
			currentPage = page; 
 
			$('.label').unbind('mouseover', fadeIn); 
			$('.label').unbind('mouseout', fadeOut); 
 
			$('#scrollable').clearQueue(); 
 
			$('#scrollable').queue(hideLabel); 
			$('#scrollable').queue(scroll(position)); 
			$('#scrollable').queue(showLabel); 
		} 
	}

The bindings to the buttons also need to be changed so that the page values are sent to navigate():

	$(document).ready(function() 
		{ 
 
			$('#scroll1').click(function() 
				{ 
					navigate(0,1); 
				} 
			); 
 
			$('#scroll2').click(function() 
				{ 
					navigate('-600',2); 
				} 
			); 
 
			$('#scroll3').click(function() 
				{ 
					navigate('-1200',3); 
				} 
			); 
 
			$('#scroll4').click(function() 
				{ 
					navigate('-1800',4); 
				} 
			); 
 
			$('.label').bind('mouseover', fadeIn); 
			$('.label').bind('mouseout', fadeOut); 
 
			$('#label').css("opacity", "0.7"); 
		} 
	);

Summary

In this tutorial you learnt how to create a simple showcase widget. You used HTML and CSS to style it and most importantly used the overflow property to limit the view of the viewport. Queuing and dequeuing events with jQuery enables you to execute events asynchronously and binding and unbinding events enables you to exert more control over the UI to prevent unnecessary animation. This example is easily extend to create more sections. You just need to make sure the widths of #content, #scrollable and #label divs are expanded to including the extra sections that you wish (remember – 600px per section) and of course, add an extra section in the #content div and a related label in the #labels div.

You can download this tutorial’s source code here.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.topz10s.com Amrinder Singh

    Great work Man I like each and every thing about Jquery

  • http://jakubmiziolek.pl Jakub

    Thanks Tim!
    After going through your tutorial i finally fell more comfortable with making some more advanced jQ animations. I’ve learned a lot :)

  • http://www.aestheticdesign.com Matt

    Is that supposed to be a working example at the top? I tried it in Safari and Chrome and nothing happens with the four grey thumbnail boxes.

  • Roberto

    How I can leave autoslide this example?… thanks

  • http://axolotl.ch sinun

    Hi
    Interesting stuff. Sorry, but can’t find the demo button. Would’nt it be helpfull to have preview?

  • Timid

    Thx Tim. Nice.

    However an online working demo would be handy. Then one can see in a glance of the demo creates the desired effect.

  • http://www.titan21.co.uk Tim Smith

    By popular demand – there is an example of the showcase at http://code.titan21.co.uk/df/scrollingviewpoint/

    • vicky

      i went to your titan site to view the demo and using only keyboard, the pictures appear twice: first with h1 heading then second time with the labels. how can the heading, picture and label appear together once? [i am blind]

  • http://www.paulund.co.uk Paul

    Nice tutorial thanks for this example.

  • http://www.joezimjs.com JoeZim

    There’s no indicator of which slide we’re on.

  • Beatriz

    Hi,

    Thank you for sharing this with us. I’m trying to do this using a word press theme. Please let me know where do I enter the js file.

    Thanks, Bea

  • http://freenservices.wix.com/consulting Fred

    So I was playing around with this and changed the picture size to 700 by 300. I did the math where the content and section would be 2800 but now the picture show up in the slider with extra space at the end. Which setting am I missing? This seems pretty straight forward. I was able to set my photos to 700 by 300 first.