Animated Buttons using CSS3 Transitions and Transforms

Alt Text

Introduction

As CSS3 is gradually more supported over popular browsers, CSS3 Buttons become great looking replacements for image and script heavy buttons. These buttons use CSS3 transitions and transforms to animate morphing icons to represent different functions. This is a simple demonstration of 5 buttons representing functions like Demo, Download, Digg, Email, and RSS. I may make more if the response is very positive about these buttons.

Important Note: This is only supported in Safari, Chrome, and Firefox 5+ (not yet released), and maybe in IE 10+ (also unreleased)

Check out another tutorial using the same techniques to create an animated navigation: Animated Navigation Using CSS3

HTML

This is the basic structure for all the buttons. The class of the button container determines which animation it will do. There are 5 classes for each different button: demo, download, digg, email, and rss.

<div id="button-container" class="demo">
		<a href="#" id="button">Demo</a>
			<div id="arrow-container">
				<div id="arrow-rectangle">
				</div>
				<div id="arrow-triangle" >
				</div>
			</div>
	</div>

CSS

First, here is the CSS styles to make the basic appearance of the button.

body{
	margin: 0;
}

a{
	text-decoration:none
}

#button-container{
	position: relative; /*Important, Keeps the CSS3 Shapes in place*/
	margin: 10px;
	width: 220px;
	height: 50px;
}

#button{
	float: left;
	width: 200px;
	height: 50px;
	line-height: 50px;
	background-color: #ddd;
	padding-left: 20px;
	
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px;

	-moz-box-shadow:0 2px 0 #4c9434;
	-webkit-box-shadow:0 2px 0 #4c9434;
	box-shadow:0 2px 0 #4c9434;

	background-image: -webkit-gradient(
	    linear,
	    left bottom,
	    left top,
	    color-stop(0, #60B842),
	    color-stop(0.85, #7FD13D)
	);
	background-image: -moz-linear-gradient(
	    center bottom,
	    #60B842 0%,
	    #7FD13D 85%
	);

	color:#fff;
	font-family:arial,helvetica,sans-serif;
	font-size:17px;
	font-weight:bold;
	text-shadow:1px 1px 1px #4c9434;
}

#button:hover{
	background-image: -webkit-gradient(
	    linear,
	    left bottom,
	    left top,
	    color-stop(0, #6DD14B),
	    color-stop(0.85, #85DB40)
	);
	background-image: -moz-linear-gradient(
	    center bottom,
	    #6DD14B 0%,
	    #85DB40 85%
	);
	box-shadow:0 2px 0 #5EA839;
}

#button:active{
	background-image: -webkit-gradient(
	    linear,
	    left bottom,
	    left top,
	    color-stop(0, #6DD14B),
	    color-stop(0.85, #85DB40)
	);
	background-image: -moz-linear-gradient(
	    center bottom,
	    #6DD14B 0%,
	    #85DB40 85%
	);
	box-shadow:0 1px 0 #5EA839;
	margin-top: 1px;
}

This alone makes for a nice looking CSS3 button. But now we want to add animated icons. First we must make the shapes to manipulate and morph into different icons. The basic starting icon I want for all the buttons is an arrow. Here are the components of the arrow:

/*Shapes and Components*/

	#arrow-container{
		position: absolute;
		top:0px;
		right: 0px;
		margin: 15px;
		box-shadow: 10px 10px;
		width: 35px;
		height: 20px;
		-webkit-transition: -webkit-transform 0.3s ease-out;
		-moz-transition: -moz-transform 0.3s ease-out;
		transition: transform 0.3s ease-out;
	}
	#arrow-rectangle{
		float: left;
		margin-top: 5px;
		width: 15px;
		height: 10px;
		background-color: #44801c;
		-webkit-transition: -webkit-transform 0.3s ease-out;
		-moz-transition: -moz-transform 0.3s ease-out;
		transition: transform 0.3s ease-out;
	}
	#arrow-rectangle-handle{
		float: left;
		margin-top: 5px;
		border-color: #44801c;
		border-style: solid;
		border-width: 5px;
		-webkit-transition: -webkit-transform 0.3s ease-out;
		-moz-transition: -moz-transform 0.3s ease-out;
		transition: transform 0.3s ease-out;
	}
	#arrow-rectangle-staff{
		float: left;
		margin-top: 5px;
		width: 5px;
		height: 10px;
		background-color: #44801c;
		-webkit-transition: -webkit-transform 0.3s ease-out;
		-moz-transition: -moz-transform 0.3s ease-out;
		transition: transform 0.3s ease-out;
	}
	#arrow-triangle{
		float: left;
		border-color: transparent transparent transparent #44801c;
		border-style: solid;
		border-width: 10px;
		height: 0px;
		width: 0px;
		-webkit-transition: -webkit-transform 0.2s ease-out;
		-moz-transition: -moz-transform 0.2s ease-out;
		transition: transform 0.2s ease-out;
	}

Every icon uses 1 arrow-rectangle and 1 arrow-triangle to create the arrow. The Digg button is the exception because it needs slightly more complex transforms and needs to different rectangles: the arrow-rectangle-staff and the arrow-rectangle-handle. You can change the duration of the transition to your liking, but I found it looks better when it is fast.

Finally, here are the transforms to create the animated morphing effect.

	/*Animations*/

	.rotateDown{
	  	-webkit-transform: rotateZ(90deg) translateX(5px);
	    -moz-transform: rotateZ(90deg) translateX(5px);
	    transform: rotateZ(90deg) translateX(5px);
	}
	.rotateDownMore{
	  	-webkit-transform: rotateZ(90deg) translateX(15px);
	    -moz-transform: rotateZ(90deg) translateX(15px);
	    transform: rotateZ(90deg) translateX(15px);
	}
	.rotate{
	  	-webkit-transform: rotateZ(90deg);
	    -moz-transform: rotateZ(90deg);
	    transform: rotateZ(90deg);
	}
	.change{
	  	-webkit-transform: scale(0.4) rotateZ(-180deg);
	    -moz-transform: scale(0.4) rotateZ(180deg);
	    transform: scale(0.4) rotateZ(180deg);
	}
	.widen{
	  	-webkit-transform: scaleY(2) translateX(10px);
	    -moz-transform: scaleY(2) translateX(10px);
	    transform: scaleY(2) translateX(10px);
	}
	
	/*Digg Animations*/
	
	.skinny{
		-webkit-transform: scaleY(.5) scaleX(4);
	    -moz-transform: scaleY(.5) scaleX(4);
	    transform: scaleY(.5) scaleX(4);	
	}
	#arrow-rectangle-handle.donut{
		-webkit-transform: scale(1.5) translateX(-14px);
	    -moz-transform: scale(1.5) translateX(-14px);
	    transform: scale(1.5) translateX(-14px);
		height: 5px;
		width: 5px;
		border-width: 2.5px;
	}
	#arrow-triangle.shovel{
		-webkit-transform: rotateZ(-135deg) translateX(8px) translateY(-8px);
	    -moz-transform: rotateZ(-135deg) translateX(8px) translateY(-8px);
	    transform: rotateZ(-135deg) translateX(8px) translateY(-8px);
		border-color: transparent transparent #44801c #44801c;
		border-radius: 7px;
	}
	
	/*Email Animations*/
	
	#arrow-triangle.emailRotate{
	  	-webkit-transform: scale(1.34) scaleY(.7) rotateZ(90deg) translateX(2px) translateY(13.9px);
	    -moz-transform: scale(1.34) scaleY(.7) rotateZ(90deg) translateX(2px) translateY(13.9px);
	    transform: scale(1.34) scaleY(.7) rotateZ(90deg) translateX(2px) translateY(13.9px);
		border-color: transparent transparent transparent #2A4F11;
	}
	.emailTranslate{
	  	-webkit-transform: scale(1.5) scaleX(1.2);
	    -moz-transform: scale(1.5) scaleX(1.2);
	    transform: scale(1.5) scaleX(1.2);
	}
	
	/*RSS Animations*/

	#arrow-triangle.rss{
		-webkit-transform: rotateZ(180deg) translateY(20px);
	    -moz-transform: rotateZ(180deg) translateY(20px);
	    transform: rotateZ(180deg) translateY(20px);
		border-radius: 30px;
		border-width: 10px;
		border-style: double;
		width: 10px;
		height: 10px;
	}
	.rssDot{
		-webkit-transform: scaleX(.7) scale(.5) translateX(20px);
	    -moz-transform: rotateZ(180deg) translateY(20px);
	    transform: rotateZ(180deg) translateY(20px);
		border-radius: 30px;
	}

jQuery

Now all thats left is a way to trigger the classes on hover.

(function($){
	$(function(){


	$('#button-container.demo').hover(
			  function () {
			    $('#button-container.demo #arrow-container').addClass('rotate');
				$('#button-container.demo #arrow-triangle').addClass('change');
				$('#button-container.demo #arrow-rectangle').addClass('widen');
			  }, 
			  function () {
			    $('#button-container.demo #arrow-container').removeClass('rotate');
				$('#button-container.demo #arrow-triangle').removeClass('change');
				$('#button-container.demo #arrow-rectangle').removeClass('widen');
			  }
	);
	
	$('#button-container.download').hover(
			  function () {
			    $('#button-container.download #arrow-container').addClass('rotateDown');
			  }, 
			  function () {
			    $('#button-container.download #arrow-container').removeClass('rotateDown');
			  }
	);
	
	$('#button-container.digg').hover(
			  function () {
			    $('#button-container.digg #arrow-container').addClass('rotateDownMore');
				$('#button-container.digg #arrow-rectangle-handle').addClass('donut');
				$('#button-container.digg #arrow-rectangle-staff').addClass('skinny');
				$('#button-container.digg #arrow-triangle').addClass('shovel');
			  }, 
			  function () {
			    $('#button-container.digg #arrow-container').removeClass('rotateDownMore');
				$('#button-container.digg #arrow-rectangle-handle').removeClass('donut');
			 	$('#button-container.digg #arrow-rectangle-staff').removeClass('skinny');
				$('#button-container.digg #arrow-triangle').removeClass('shovel');
			 }
	);
	
	$('#button-container.email').hover(
			  function () {
				$('#button-container.email #arrow-triangle').addClass('emailRotate');
				$('#button-container.email #arrow-rectangle').addClass('emailTranslate');
			  }, 
			  function () {
				$('#button-container.email #arrow-triangle').removeClass('emailRotate');
				$('#button-container.email #arrow-rectangle').removeClass('emailTranslate');
			 }
	);
	
	$('#button-container.rss').hover(
			  function () {
				$('#button-container.rss #arrow-triangle').addClass('rss');
				$('#button-container.rss #arrow-rectangle').addClass('rssDot');				
			  }, 
			  function () {
				$('#button-container.rss #arrow-triangle').removeClass('rss');
				$('#button-container.rss #arrow-rectangle').removeClass('rssDot');
			 }
	);
	
	
	}); // end of document ready
})(jQuery); // end of jQuery name space

Conclusion

If you are confused on how the CSS3 animation is done please read these resources:

Using CSS3 Transitions, Transforms and Animation
CSS Fundamentals: CSS 3 Transitions
W3Schools: CSS3 transform Property

Important Note: This is only supported in Safari, Chrome, and Firefox 5+ (not yet released), and maybe in IE 10+ (also unreleased)