CSS3 Animated Photo Stack with jQuery

View Demo

CSS3 transitions and animations are rightly attracting a lot of attention. With support in most modern browsers, there is a lot of scope for creating rich user experiences using only CSS. In this post, I will walk through how to create a stack of photos using CSS keyframe animations and a dash of jQuery to achieve a pretty awesome effect.

So, lets dive straight in! The markup is pretty straightforward, you just need a container filled with the images for the stack of photos:

<div id="photo_stack">
	<img id="photo1" src="images/photostack1.jpg" alt="Alt text goes here..." />
	<img id="photo2" src="images/photostack2.jpg" alt="Alt text goes here..." />
	<img id="photo3" src="images/photostack3.jpg" alt="Alt text goes here..." />
</div>

You will then need some simple CSS to style and position the images in a stack. We will be using jQuery to alter the z-index values of each image once the animation has completed, so we will start by giving each image a high z-index value. You will also need to setup the speed and easing functions for the transitions.

#photo_stack img {
	position: absolute;
	border: 10px solid #FFF;
	box-shadow: 2px 2px 8px rgba(0,0,0,0.5);
	-moz-box-shadow: 2px 2px 8px rgba(0,0,0,0.5);
	-webkit-box-shadow: 2px 2px 8px rgba(0,0,0,0.5);
	z-index: 9999;

	/* setup transition speed and easing */
	-moz-transition: all 0.2s ease; /* Firefox */
	-webkit-transition: all 0.2s ease; /* WebKit */
	-o-transition: all 0.2s ease; /* Opera */
	transition: all 0.2s ease; /* Standard */

}
#photo_stack #photo1 {
	top: 0;
	left: 100px;
}
#photo_stack #photo2 {
	top: 12px;
	left: 55px;
}
#photo_stack #photo3 {
	top: 27px;
	left: 50px;
}

Once this is complete you can add the CSS to create the keyframe animation, which will take the image at the top of the stack and place it at the bottom of the photo stack.

@-webkit-keyframes shuffle {
	0% {
		margin-left: 0px;
	}
	50% {
		margin-left: 450px;
		-webkit-transform: scale(0.9);
		-moz-transform: scale(0.9);
		transform: scale(0.9);
	}
	100% {
		margin-left: 0px;
		-webkit-transform: scale(1);
		-moz-transform: scale(1);
		transform: scale(1);
	}
}
#photo_stack .animate {
	-webkit-animation-name: shuffle;
	-webkit-animation-duration: 1s;
	-webkit-animation-iteration-count: 1;
}

What this is basically doing, is running the keyframe animation called ’shuffle’ once and for a duration of 1 second. The animation itself is moving the image 450px to the right of the stack, scaling down to give an impression of depth, and then moving it back to where it’s original position. Note that this will only happen when the image is assigned the ‘animate’ class.

Okay, so you now have a cool animation effect, but nothing triggers it and the image does not go to the bottom of the stack: Enter jquery. What jquery will do, is trigger the animation by assigning the ‘animate’ class to the image on the top of the stack, removing it once the animation is complete.

$imgs = $("#photo_stack img");
$imgCount = $imgs.length;
$curr_index = 0;
$imgs.last().addClass('current'); /* Set the image at top of stack to current */

$("#photo_stack")
	.delegate('img', 'click', function() {
		$this = $(this);

		/* If the image is at the top of the stack */
		if ($this.hasClass('current')) {
			/* Work out new z-index value */
			$zi = $this.css('zIndex') - $imgCount;

			/* Trigger animation */
			$this.addClass('animate');

			/* Assign new z-index value then stop animation after complete */
			setTimeout(function() { $this.css('zIndex', $zi); }, 200);
			setTimeout(function() { $this.removeClass('animate'); }, 1000);

			/* Set next image to current */
			$this.removeClass('current');
			if ($this.index() == 0) {
				$imgs.last().addClass('current');
			} else {
				$imgs.eq($this.index()-1).addClass('current');
			}
		}
	})

You will now have some images in a stack that you can click on and they will be animated and placed to the bottom of the stack. Now it is time to use the rotation transition to make the photo stack look a little more realistic. I used CSS classes to rotate the images somewhere between -4 and 4 degrees and used jQuery to randomly assign one of those classes to each image when the DOM has loaded. Then I just added a CSS rule to rotate the image to 0 degrees on hover.

#photo_stack .deg1 {
	-webkit-transform: rotate(1deg);
   	-moz-transform: rotate(1deg);
   	transform: rotate(1deg);
}
#photo_stack .deg2 {
	-webkit-transform: rotate(2deg);
   	-moz-transform: rotate(2deg);
   	transform: rotate(2deg);
}
#photo_stack .deg3 {
	-webkit-transform: rotate(3deg);
   	-moz-transform: rotate(3deg);
   	transform: rotate(3deg);
}
#photo_stack .deg4 {
	-webkit-transform: rotate(4deg);
   	-moz-transform: rotate(4deg);
   	transform: rotate(4deg);
}
#photo_stack .deg1neg {
	-webkit-transform: rotate(-1deg);
   	-moz-transform: rotate(-1deg);
   	transform: rotate(-1deg);
}
#photo_stack .deg2neg {
	-webkit-transform: rotate(-2deg);
   	-moz-transform: rotate(-2deg);
   	transform: rotate(-2deg);
}
#photo_stack .deg3neg {
	-webkit-transform: rotate(-3deg);
   	-moz-transform: rotate(-3deg);
   	transform: rotate(-3deg);
}
#photo_stack .deg4neg {
	-webkit-transform: rotate(-4deg);
   	-moz-transform: rotate(-4deg);
   	transform: rotate(-4deg);
}
#photo_stack .hover {
	-webkit-transform: rotate(0deg);
   	-moz-transform: rotate(0deg);
   	transform: rotate(0deg);
	cursor: pointer;
}

I chose to use this approach, as it means that you can have any number of images in the stack, and they will be randomly rotated. If you wanted, you could just assign a specific angle to each photo in the stack using each images ID for complete control.

The full code for the animated photo stack can be found on the demo page. It works best in the latest version of Chrome or Safari. Firefox works but without the animation and I did not even bother checking Internet Explorer – it always spoils the party!

Tagged as

Leave a Reply

css gallery