Animated CSS3 Photo Stack

Animated CSS3 Photo Stack

In this tutorial, we are going to build an animated photo stack, which will use all kinds of fancy effects to transition between a set of images. The effects are implemented purely using CSS3, which means that they run smoothly on modern browsers and mobile devices. We will also make the photo stack advance automatically, so you can use it as a slideshow.

The HTML

As always, the first step is to present the markup of the example. We are starting with a regular HTML5 document in which we are including a number of CSS/JS files:

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />

	<title>Animated CSS3 Photo Stack | Tutorialzine Demo</title>

	<!-- CSS Includes -->
	<link href="assets/css/style.css" rel="stylesheet" />
	<link href="assets/css/animate.css" rel="stylesheet" />

</head>
<body>

	<ul id="photos">
		<li><a href="http://www.flickr.com/photos/brockwhittaker/8500935165/"
		style="background-image:url(...)">Landscape 5</a></li>
		<!-- More photos here -->
	</ul>

	<a href="#" class="arrow previous"></a>
	<a href="#" class="arrow next"></a>

	<!-- Libraries -->
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	<script src="assets/js/script.js"></script>

</body>
</html>

The #photos UL holds the photos that we will be animating. For each photo, I’ve defined a LI item with an anchor element inside it. The image is set as the background-image property of the link. As you will see in the CSS part, I am using the background-size property to force the image to cover the entire width and height of the link. When adding more photos, keep in mind that because they are positioned absolutely, they will be shown in reverse order (the last photo will be at the top).

In the head section of the document, I am including our main stylesheet and animate.css – the library that gives us those wonderful CSS3 animations. Before the closing body tag, we have the jQuery library and script.js which we will discuss next.

Animated CSS3 Photo Stack

Animated CSS3 Photo Stack

The JavaScript

To trigger the effects that the animate library gives us, we have to assign a class name to the element with the name of the animation. We will also have to move the animated photo at the bottom of the stack after the animation finishes, so that we can show the next image. Here is what we need to do in order to make this example work:

  • First, we will listen for clicks on the arrows;
  • Then, when a click occurs on the next arrow, we will trigger a randomly chosen CSS animation by assigning a class name to the topmost element of the stack (this is actually the last LI item because of the positioning);
  • After one second, when the animation completes, we will move the animated element before the other LIs with the prependTo jQuery method (this will push it to the bottom of the stack) and remove the classes that we’ve assigned above.
  • For the previous arrow, we will do nearly the same, with the only difference being that we will take the last image and place it at the top of the stack before triggering the animation.

In addition, I will also add auto-advance functionality like we did in this article. This will turn the example into a cool slideshow that stops the automated transitions when you click one of the arrows.

Here is what the code looks like:

assets/js/script.js

$(function() {

	var exits = ['fadeOut', 'fadeOutDown', 'fadeOutUpBig', 'bounceOut', 'bounceOutDown',
		'hinge', 'bounceOutUp', 'bounceOutLeft', 'rotateOut', 'rotateOutUpLeft',
		'lightSpeedOut', 'rollOut'];

	var entrances = ['fadeIn', 'fadeInDown', 'fadeInRight', 'bounceIn', 'bounceInRight',
			'rotateIn', 'rotateInDownLeft', 'lightSpeedIn', 'rollIn', 'bounceInDown']; 

	var photos = $('#photos'),
		ignoreClicks = false;

	$('.arrow').click(function(e, simulated){
		if(ignoreClicks){

			// If clicks on the arrows should be ignored,
			// stop the event from triggering the rest
			// of the handlers

			e.stopImmediatePropagation();
			return false;
		}

		// Otherwise allow this click to proceed,
		// but raise the ignoreClicks flag

		ignoreClicks = true;

		if(!simulated){
			// Once the user clicks on the arrows,
			// stop the automatic slideshow
			clearInterval(slideshow);
		}
	});

	// Listen for clicks on the next arrow
	$('.arrow.next').click(function(e){

		e.preventDefault();

		// The topmost element
		var elem = $('#photos li:last');

		// Apply a random exit animation
		elem.addClass('animated')
			.addClass( exits[Math.floor(exits.length*Math.random())] );

		setTimeout(function(){

			// Reset the classes
			elem.attr('class','').prependTo(photos);

			// The animation is complate!
			// Allow clicks again:
			ignoreClicks = false;

		},1000);
	});

	// Listen for clicks on the previous arrow
	$('.arrow.previous').click(function(e){

		e.preventDefault();

		// The bottom-most element
		var elem = $('#photos li:first');

		// Move the photo to the top, and
		// apply a random entrance animation

		elem.appendTo(photos)
			.addClass('animated')
			.addClass( entrances[Math.floor(entrances.length*Math.random())] );

		setTimeout(function(){

			// Remove the classess
			elem.attr('class','');

			// The animation is complate!
			// Allow clicks again:
			ignoreClicks = false;

		},1000);
	});

	// Start an automatic slideshow
	var slideshow = setInterval(function(){

		// Simulate a click every 1.5 seconds
		$('.arrow.next').trigger('click',[true]);

	}, 1500);

});

I haven’t used all the effects that animate.css provides, but you can find a full list at its github page.

All that we are left to do, is to write a few CSS styles.

The CSS

I won’t be showing all of the styles here, only those that are directly responsible for the photo stack:

assets/css/styles.css

#photos{
	margin:0 auto;
	padding-top:120px;
	width:450px;
	position:relative;
}

#photos li{
	position:absolute;
	width:450px;
	height:450px;
	overflow:hidden;
	background-color:#fff;
	box-shadow: 1px 1px 1px #ccc;
	z-index:10;

	-webkit-animation-duration: 1s;
	-moz-animation-duration: 1s;
	animation-duration: 1s;
}

#photos li a{
	position:absolute;
	top:6px;
	left:6px;
	right:6px;
	bottom:6px;
	background-size: cover;
	text-indent:-9999px;
	overflow:hidden;
}

To change the duration of the animations, you will have to supply the animation-duration property. In the fragment above, I have set it to 1 second. More properties that you can set are animation-delay for the delay before the animation is triggered, and animation-iteration-count for the number of repetitions.

Done!

With this our animated photo stack effect is complete! You can use this example as a lightweight slideshow that works smoothly even on mobile devices.

Join our newsletter and get our PSDs!18,835 people learn about HTML5, JS and more. Join them!

by Martin Angelov

Martin is a web developer with an eye for design from Bulgaria. He founded Tutorialzine in 2009 and it still is his favorite side project.

14 Comments

  1. nice, but unwanted scroll that appears in small screen (like 800×600) can be easily avoided :)

  2. humbu says:

    This is great i will include this to my new project thanks for sharing

  3. Casco Romano says:

    Very good and original Martin, I wait to be able to use it in a near(next) project.
    Regards and thank you very much

  4. iman says:

    like
    i have problem with overflow

  5. armin says:

    Excellent as always

  6. inayahs says:

    wow, excellent tutorial this i am learn something new about html,css. Thanks...

  7. BiBi says:

    Hi Martin, I always see special something in your tuts, thanks, I will use it for my projects.

  8. Faisy says:

    Another great tutorial, thanks for sharing.

  9. Great Post and Tutorial. The photo stack effect is really nice. Thanks for sharing.

  10. uday says:

    Hi Martin.
    Its good. Amazing Stunning movements.Any way thanks for sharing.....

  11. fblin says:

    Thank you for this nice tutorial, you rock :) !

  12. Awais Raza says:

    Good effect, and easy to learn. Keep it up Martin.

  13. benz says:

    I like this effect so much, thanks for sharing :)

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links