Meaningful transitions tutorial basing on material design motion choreography

Some time ago I got inspired by Googles material design and meaningful transition concepts. Since CSS3 has allowed us to build beautiful transitions and seamless animations we must also be very careful in using them. It is our responsibility in front of our users and it can either help to better understand, read and grasp the information or do the opposite.

If a client would enter your restaurant, you would take proper care of him e.g. show him his table, present the menu etc. On the web we have other options to guide the user that has arrived – one of them being visual guidance using proper and logical information entrance animations. If a user does an action, we want to give him both the feedback of his action and display the following information so that he feels that it was connected to his action.

View the demo or Download source

Meaningful transition setup – CSS + Bootstrap + Animate.css

We are basing our example on Bootstrap in order to handle responsiveness and we use Animate.css because it is a great library for CSS based animations and transitions. Tutorial consists of 3 cards than can be opened via clicking on it. After the card has been clicked, additional information is shown and loaded dynamically using Ajax.

<div class="col-sm-4 card">
	<div class="card-content">
		<div class="left">
			<a class="close-button hidden" href="#" title=""></a>
			<div class="background-color-filler"></div>
			<img class="animate-transition" src="images/meaningful-transition-design-1.svg"/>
			<div class="button-wrapper open-card">
				<a href="#" title="">Open</a>

You can see that our card consists of a close button that we reveal when the card is open, background color, an icon for the card and a button that opens the card itself. Please note that we do have a class “left” defined here – I will explain why later on.

The magic of motion – jQuery + jQuery UI + Transform2d.js

After clicking on a card we want to show the user that the current card opens up and what better way to do that than to create the feeling that we are immersing in it zooming in a large circle right from the center of the card.

In order to do the zooming effect – we are using CSS scale property, but since it is not so stable and reliable across browsers, we are adding additional jQuery plugin Transform2d.js in combination with jQuery UI that consists of Effects components which is needed to create the animation of the circle. We will also need to include jQuery library in order to handle the opening and closing of cards.

//Function responsible for meaningful transitions

$( ".open-card, .card img, .background-color-filler, .close-button" ).bind( "click", function(event) {

	var body = $("body");
	var row = $(this).parent().parent().parent().parent();
	var card = $(this).parent().parent().parent();
	var left = $(this).parent();
	var background = $(this).parent().find(".background-color-filler");
	var image = $(this).parent().find("img");
	var closeButton = $(this).parent().find(".close-button");
	var openButton = $(this).parent().find(".open-card");

	var speed = 600;

	$(".open-card").removeClass("animated fadeInDown"); //Removes animation classes from all buttons

	if (card.hasClass('clicked')) { //If the card is open
		body.removeClass("card-is-open"); //Removes definition that the card is open
		card.removeClass('open'); //Removes class that shows that the card is open
		$("#dynamic-content").remove(); //Destroys dynamic content container
		closeButton.addClass("hidden"); //Hides close button
		image.removeClass("animated fadeOut").addClass("animated fadeIn"); //Reveal back the image
		openButton.removeClass("animated fadeOutUp").addClass("animated fadeInDown");
		row.removeClass('row-open'); //Revealing back the hidden cards

			transform: 'scale(1)' //Circle animation to the initial size
		}, speed, 'easeOutCubic', function(){
			//These functions are fired after the animation
			card.removeClass('clicked'); //Removes class after a card is clicked
			body.removeClass("hide-overflow-x"); //Returns vertical scrollbar after the animation
			$('html, body').animate({ //Used to scroll down back to the card
				scrollTop: card.offset().top - 50
			}, {"duration": speed});

	} else { //If the card is not open

		card.addClass('clicked'); //Adds a class after a card is clicked
		body.addClass("hide-overflow-x"); //Adds a class in order to hide vertical scrollbars that appear after the animation is finished
		openButton.addClass("animated fadeOutUp"); //Hides the button on the card that is clicked
		image.addClass("animated fadeOut"); //Hides the image on the card that is clicked

			transform: 'scale(300)' //Circle animation
		}, speed, 'easeInCubic', function(){
			//These functions are fired after the animation				
			body.addClass("card-is-open"); //Adds class to the body when the animation is finished and the circle is fully scaled
			row.addClass('row-open'); //Adds a class to the row that is open in order to hide the cards it holds using CSS
			left.after( "<div id='dynamic-content' class='right animated fadeInUp'>This is dynamic content</div>" ); //Loads dynamic content element for use with Ajax calls
			closeButton.removeClass("hidden").addClass('animated fadeInUp'); //Reveals close button
			card.addClass('open'); //Adds a class after the card is clicked and opened
			image.removeClass("animated fadeOut").addClass('animated fadeIn'); //Reveals back the image
			$("#dynamic-content").load('dynamic-content.html'); //Ajax call to load the dynamic content from a file or a link

			$('html, body').animate({ //Used to scroll down back to the card
				scrollTop: card.offset().top - 50
			}, speed);


The JavaScript code above has got all of the comments and you can easily read what each line does and why is it there. This is the place where we are using Ajax to load the content of the open card and here we can see that we have class “right” to the dynamic content that is being loaded. This is why previously I mentioned we needed the class “left” defined – both these parts are loaded together and this is how we are aligning them side by side once they are visible.

View the demo or Download source

In categories: Tutorials, Website development

Nauris Kolāts

Nauris is a freelance designer / developer who loves to dig into the UX as much as in the ground for fishing worms. And fishing is just one amongst the long list of his active lifestyle hobbies.

Other posts

Your thoughts

Latest work