Full Page Image Gallery with jQuery

In this tutorial we are going to create a stunning full page gallery with scrollable thumbnails and a scrollable full screen preview. The idea is to have a thumbnails bar […]

In this tutorial we are going to create a stunning full page gallery with scrollable thumbnails and a scrollable full screen preview. The idea is to have a thumbnails bar at the bottom of the page that scrolls automatically when the user moves the mouse. When a thumbnail is clicked, it moves to the center of the page and the full screen image is loaded in the background. Now the user can move up and down and the image will get scrolled automatically, giving him the opportunity to see all of the image.

We will use some CSS3 Webkit properties to enhance the look and jQuery for the functionality.
That’s why the demo is best viewed in Webkit browsers like Google Chrome or Apple Safari.

We will be using the awesome jQuery thumbnail scroller by Malihu. Big thanks to him for this great and smooth script!

Again, we will be showing some amazing photography by Mark Sebastian. Please visit his Flickr page or his homepage for more information on his work. The images that we will be using are from “The IT Factor” photo set on Flickr.

So, let’s begin!

The Markup

The HTML consists of a main wrapper div for the gallery. Inside of that wrapper we will have the full screen image, an overlay for a nice halftone pattern effect, a loading div, the navigation items and the thumbnails bar:

<div id="fp_gallery" class="fp_gallery">
	<img src="images/1.jpg" alt="" id="preview" class="fp_preview" style="display:none;"/>
	<div class="fp_overlay"></div>
	<div id="fp_loading" class="fp_loading"></div>
	<div id="fp_next" class="fp_next"></div>
	<div id="fp_prev" class="fp_prev"></div>
	<div id="outer_container">
		<div id="thumbScroller">
			<div class="container">
				<div class="content">
					<div><a href="#"><img src="images/thumbs/1.jpg" alt="images/1.jpg" class="thumb" /></a></div>
				</div>
				<div class="content">
					<div><a href="#"><img src="images/thumbs/2.jpg" alt="images/2.jpg" class="thumb" /></a></div>
				</div>
				...
			</div>
		</div>
	</div>
	<div id="fp_thumbtoggle" class="fp_thumbtoggle">View Thumbs</div>
</div>

We will also add a “View Thumbnails” div that will appear when the thumbnails are hidden.
We are using (abusing) the alt attribute of the image to keep the path to the full image.
Let’s take a look at the style.

The CSS

First, we will reset the style and define some main properties for the body:

*{
	margin:0;
	padding:0;
}
body {
	background:#212121;
	overflow:hidden;
	font-family:Arial, Helvetica, sans-serif;
	text-transform:uppercase;
	color:#fff;
	font-size:10px;
}

In the following, we will define the style for the scrollable thumbs container. Most of the style is adapted from Malihu’s thumbnail scroller. We just edited some padding and margins and added a webkit reflection to the whole container:

#outer_container{
	position:fixed;
	bottom:-160px;
	margin:0px 0px 30px 0px;
	height:130px;
	padding:0;
	-webkit-box-reflect:
		below 5px -webkit-gradient(
			linear,
			left top,
			left bottom,
			from(transparent),
			color-stop(0.6, transparent),
			to(rgb(18, 18, 18))
		);
}

The bottom value of the container is negative in order to hide the thumbnails bar. When we load the page, we show the bar.

The following classes define the style of the inner elements of the thumbnail container:

#thumbScroller{
	position:relative;
	overflow:hidden;
}
#thumbScroller .container{
	position:relative;
	left:0;
}
#thumbScroller .content{
	float:left;
}
#thumbScroller .content div{
	margin:2px;
	height:100%;
}

The thumbnail images are going to have a thick white border and we will restrict their height to 120px:

#thumbScroller img,
img.clone{
	border:5px solid #fff;
	height:120px;
}
#thumbScroller a{
	padding:2px;
	outline:none;
}

The halftone pattern is shown by the overlay element which will be stretched over all the screen and move when we scroll since it is fixed:

.fp_overlay{
	width:100%;
	height:100%;
	position:fixed;
	top:0px;
	left:0px;
	background:transparent url(../images/icons/pattern2.png) repeat-x bottom left;
}

The loading div will appear whenever we click on an image and wait for the full image to load. It will be centered on the screen with the help of the “50% trick”:

.fp_loading{
	display:none;
	position:fixed;
	top:50%;
	left:50%;
	margin:-35px 0px 0px -35px;
	background:#000 url(../images/icons/loader.gif) no-repeat center center;
	width:70px;
	height:70px;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px;
	z-index:999;
	opacity:0.7;
}

The navigation elements will be styled as follows:

.fp_next,
.fp_prev{
	width:50px;
	height:50px;
	position:fixed;
	top:50%;
	margin-top:-15px;
	cursor:pointer;
	opacity:0.5;
}
.fp_next:hover,
.fp_prev:hover{
	opacity:0.9;
}
.fp_next{
	background:#000 url(../images/icons/next.png) no-repeat center center;
	right:-50px;
}
.fp_prev{
	background:#000 url(../images/icons/prev.png) no-repeat center center;
	left:-50px;
}

While the navigation items will be positioned to the left and right and centered vertically, we will position the toggle item at the bottom of the page, centered horizontally:

.fp_thumbtoggle{
	height:50px;
	background:#000;
	width:200px;
	text-align:center;
	letter-spacing:1px;
	text-shadow:1px 1px 1px #000;
	position:fixed;
	left:50%;
	margin-left:-100px;
	bottom:-50px;
	line-height:50px;
	cursor:pointer;
	opacity:0.8;
}
.fp_thumbtoggle:hover{
	opacity:1.0;
}

Hovering a div will not work in every browser and can also be done with jQuery.

And finally, the style for the full image. Here we set the width to be always 100%, filling out the complete screen. This might make the image look pixelated on large screens but we have our halftone pattern to reduce the effect 🙂

img.fp_preview{
	position:absolute;
	left:0px;
	top:0px;
	width:100%;
}

Now, let’s do some magic!

The JavaScript

In the head of our HTML document we will add the jQuery thumbnail scroller by Malihu. We will be using the full size, horizontal scroller with easing. That’s why we also need to include the easing script after the inclusion of the jQuery script.

In our jQuery function we will first define some variables:

//current thumb's index being viewed
var current			= -1;
//cache some elements
var $btn_thumbs = $('#fp_thumbtoggle');
var $loader		= $('#fp_loading');
var $btn_next		= $('#fp_next');
var $btn_prev		= $('#fp_prev');
var $thumbScroller	= $('#thumbScroller');

Then we will call the function showThumbs which will make the thumbnail container appear from the bottom of the page:

showThumbs(2000);

Next, we will make the whole page scrollable vertically on mouse move. When a full sized image is loaded, we want this functionality to be available:

makeScrollable();

When we click on a thumbnail, a lot of things are going to happen. First, we will create a clone of the current thumbnail which will then move to the center of the page. Then we will load the full sized image and when it finished loading, we want the clone thumbnail to expand and fade out. We will also hide the thumbnails and show the “View thumbnails” button:

$thumbScroller.find('.content').bind('click',function(e){
	var $content= $(this);
	var $elem 	= $content.find('img');
	//keep track of the current clicked thumb
	//it will be used for the navigation arrows
	current 	= $content.index()+1;
	//get the positions of the clicked thumb
	var pos_left 	= $elem.offset().left;
	var pos_top 	= $elem.offset().top;
	//clone the thumb and place
	//the clone on the top of it
	var $clone 	= $elem.clone()
	.addClass('clone')
	.css({
		'position':'fixed',
		'left': pos_left + 'px',
		'top': pos_top + 'px'
	}).insertAfter($('BODY'));

	var windowW = $(window).width();
	var windowH = $(window).height();

	//animate the clone to the center of the page
	$clone.stop()
	.animate({
		'left': windowW/2 + 'px',
		'top': windowH/2 + 'px',
		'margin-left' :-$clone.width()/2 -5 + 'px',
		'margin-top': -$clone.height()/2 -5 + 'px'
	},500,
	function(){
		var $theClone 	= $(this);
		var ratio		= $clone.width()/120;
		var final_w		= 400*ratio;

		$loader.show();

		//expand the clone when large image is loaded
		$('<img class="fp_preview"/>').load(function(){
			var $newimg 		= $(this);
			var $currImage 	= $('#fp_gallery').children('img:first');
			$newimg.insertBefore($currImage);
			$loader.hide();
			//expand clone
			$theClone.animate({
				'opacity'		: 0,
				'top'			: windowH/2 + 'px',
				'left'			: windowW/2 + 'px',
				'margin-top'	: '-200px',
				'margin-left'	: -final_w/2 + 'px',
				'width'			: final_w + 'px',
				'height'		: '400px'
			},1000,function(){$(this).remove();});
			//now we have two large images on the page
			//fadeOut the old one so that the new one gets shown
			$currImage.fadeOut(2000,function(){
				$(this).remove();
			});
			//show the navigation arrows
			showNav();
		}).attr('src',$elem.attr('alt'));
	});
	//hide the thumbs container
	hideThumbs();
	e.preventDefault();
});

When we click on the “View thumbnails” button, we will show the thumbnails container and hide the button and the navigation elements:

$btn_thumbs.bind('click',function(){
	showThumbs(500);
	hideNav();
});

function hideThumbs(){
	$('#outer_container').stop().animate({'bottom':'-160px'},500);
	showThumbsBtn();
}

function showThumbs(speed){
	$('#outer_container').stop().animate({'bottom':'0px'},speed);
	hideThumbsBtn();
}

function hideThumbsBtn(){
	$btn_thumbs.stop().animate({'bottom':'-50px'},500);
}

function showThumbsBtn(){
	$btn_thumbs.stop().animate({'bottom':'0px'},500);
}

function hideNav(){
	$btn_next.stop().animate({'right':'-50px'},500);
	$btn_prev.stop().animate({'left':'-50px'},500);
}

function showNav(){
	$btn_next.stop().animate({'right':'0px'},500);
	$btn_prev.stop().animate({'left':'0px'},500);
}

The events for navigating through the set of images once one is loaded:

$btn_next.bind('click',showNext);
$btn_prev.bind('click',showPrev);

The next two functions will load the previous or next image and place it before the current one which will fade out:

function showNext(){
	++current;
	var $e_next	= $thumbScroller.find('.content:nth-child('+current+')');
	if($e_next.length == 0){
		current = 1;
		$e_next	= $thumbScroller.find('.content:nth-child('+current+')');
	}
	$loader.show();
	$('<img class="fp_preview"/>').load(function(){
		var $newimg 		= $(this);
		var $currImage 		= $('#fp_gallery').children('img:first');
		$newimg.insertBefore($currImage);
		$loader.hide();
		$currImage.fadeOut(2000,function(){$(this).remove();});
	}).attr('src',$e_next.find('img').attr('alt'));
}

function showPrev(){
	--current;
	var $e_next	= $thumbScroller.find('.content:nth-child('+current+')');
	if($e_next.length == 0){
		current = $thumbScroller.find('.content').length;
		$e_next	= $thumbScroller.find('.content:nth-child('+current+')');
	}
	$loader.show();
	$('<img class="fp_preview"/>').load(function(){
		var $newimg 		= $(this);
		var $currImage 		= $('#fp_gallery').children('img:first');
		$newimg.insertBefore($currImage);
		$loader.hide();
		$currImage.fadeOut(2000,function(){$(this).remove();});
	}).attr('src',$e_next.find('img').attr('alt'));
}

And finally, the makeScrollable function which will make the page scroll when the user moves the mouse up or down:

function makeScrollable(){
	$(document).bind('mousemove',function(e){
		var top = (e.pageY - $(document).scrollTop()/2) ;
		$(document).scrollTop(top);
	});
}

And that’s it!
Don’t forget to view the demo in a Webkit browser – especially in Safari you will have a divine smoothness.

We hope you liked the tutorial and the result!

Message from TestkingDownload the testking E20-001 tutorials and testking 646-563 videos with step by step testking 70-685 study guides to learn how to create inspiring web images.

Tagged with:

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 up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 102

Comments are closed.
  1. This is way too cool. I’m impressed by each of your tutorials. Thanks so much for sharing with us!

  2. Thanks so much for this. I was looking for something similar yesterday.

    Have a nice day

    Sunil

  3. Sorry – not awesome. What happens to landscape images? And if I don’t want al zoom to 5000% – ie: displaying the whole image – this won’t do.
    Don’t think about programming: it’s about usability. And here it fails.

    //DET

  4. Would be nice if this worked in webkit browsers – using slide gesture instead of mouse – so it worked on iphone/ipad/android ….

  5. Breaks in Google Chrome.
    When scrolling the main image vertically, when you go below halfway, the “View Thumbs” button jams and then stutters/smears down the page.

  6. “Luke”
    True – Breaks in Google Chrome.
    I downloaded it and tested it with Google Chrome and it just splits the background.

  7. It’s a great idea, just too bad for the Chrome Break.
    When i view it in Chrome, the thumbnail navigation goes wild,when i hover it,it disappears really quickly to the left and after a second it reappears and so on.
    Using the latest Chrome version . . .

  8. I liked this tutorial very much.I am unable to understand why images are not clear there are displayed as mosaic slide show.How to remove this mosaic effect.Please advise and guide me.
    Thanks a lot.

  9. Thank you for the great tutorials.

    I have been trying to apply a couple of your tutorials together to enable this tutorial to have prev/next image possibilities and I am quite stumped you can see how far I have got here http://boring-group.com/johnflawless I have managed to hide the scroller and also get the next image button to work but it always reverts to the first image from the set. I am sure that I am counting incorrectly… Any help gratefully received

  10. Truly awesome effect. A bit problematic from the usability point of view. May be show a smaller version of the image and then allow user to go full-size if she wants. Just a suggestion. Thanks for the tutorial.

  11. Looks really great. It’s a shame the fonts get buggy on Chrome when you scroll the photo.

  12. @Lucas, thank you, and yes, it really is a shame. I have been testing it in Chrome continuously and it seems that it has to do with its performance. When I have fewer tabs open and no other programs running everything seems fine. Hopefully, we will be able to find a fix. Cheers, ML

  13. Pretty cool!
    Although I like the the dot pattern effect (seen it in use on last fm’s player), I doubt having it on your photos in e.g. a photographer’s portfolio would be a good idea. It is much too distracting.
    Also although the fullscreen view and up and down scrolling is a nice idea ui-wise, you would usually want to have a view of the entire photo.
    Still, pretty cool indeed.

  14. Ernest Hemingway~ Theres nothing noble in being superior to your fellow men. True nobility is being superior to your former self.

  15. Love the concept, but it doesn’t work very well in Google Chrome. The text (photographer’s name and the links at the top of the page) stutters and smears down the page when I scroll up and down.

    I’m after the thumbnail layout (love it) but with the ability to view the full sized images without having to scroll. And of course, bug fixes for getting it to work correctly in Chrome. Perhaps you could consider publishing another tutorial showing how to do this?

  16. hey, love the script. Is there any ways to make an image to fit the screen, not as big(usability issues because of the top and bottom scrolling)

  17. Elegant. Thanx.
    Could you tell us how you were able to turn off browser ‘tooltips’ that used the image title? I noticed Malihu’s variation of this gallery has tooltips appearing if the mouse is over the large image. Yours doesn’t have that distraction.

  18. Great Job!, excelent desing.
    But i have a problem,, im looking for insert a image description with .attr properties in a new div, but i haven´t results ¿what ca i do?

  19. I finally found the perfect gallery, but we can’t download the pictures 🙁 Is there a way to do this?

  20. it does not work for ie6. but you add to ie6 css
    #thumbScroller .content{
    float:left;
    width:170px;
    display:inline;
    }
    this tag it work to do 🙂

  21. Very nice tutorial. Thank you for your time in making this. I cannot get the thumbnail bar to ease up from the bottom onto the page smoothly in IE Firefox or Chrome. In IE and Chrome it blinks at the top of the page and then jumps to the bottom before going transparent. In firefox, it eases from top to bottom.

    lol. any help would be great. @my url/photography.html

  22. Great gallery thanks. Would be handy to deal with landscape images in the same way it deals with portrait images.

    Also is it possible to load and image in from the start?

  23. Beautiful, but it is possible that the magnification you can see from the very beginning rather than at the end?

  24. Does this script work on an iPad type platform? Any known issues?

    Love the script and its immediate display of an image page full size, plus the scrolling thumbnails.

    We are looking to use this to display catalog pages instead of flash e-catalogs since nothing in flash works on ipads, iphones, etc…

    Is there a way to control the enlarged image so that the entire image is viewable? We noticed that part of the top or bottom seems to be cut-off or not completely scrollable… Does this have something to do with top or bottom margin settings?