CSS Animation! Making The Mac OSX Dock Fan

January 13, 2012 at 6:00 pm By
Download Demo

Mac OSX Fan Effect

So this is a piece of code I made quite a while back, which I’ve fixed up a little, removed some unnecessary coding, and hopefully created something you will enjoy! We will be recreating the Max OSX Fan Effect (quite a lovely effect, I might add), with just CSS. Let’s get started!

Animations

We’re going to be using CSS animations to accomplish this, which is going to require keyframes. The HTML below sets up 7 divs, those being 5 folders, 1 more button and a main folder which psuedo-encapsulates the other folders. All 7 divs a folder icon and some text, with 6 (not including the main folder) having a link to somewhere. The main #folder div is for some CSS and also to tie everything together. The rest can be done with CSS (and a few images).

<div id="position">
 <!-- Unnecessary, just some positioning. You can change this -->
<div id="folder">
 <!-- The folder, the main holder -->
<div id="item"><!-- An individual item, labelled 'item' -->
 <a href="http://www.html5canvastutorials.com/blog/2011/09/css3-3d-transforms-keyframes/"> <!-- The link -->
 <img src="folder.png" alt="" /> <!-- The image you want to use, we're using folders like a dock might have! -->
 Make a Flip Card in CSS <!-- The text beside the image -->
 </a></div>
<div id="item"><!-- Repeat! -->
 <a href="http://www.html5canvastutorials.com/blog/2011/08/making-website-fit-screen/">
 <img src="folder.png" alt="" />
 Make Your Website Fit any Screen
 </a></div>
<div id="item"><a href="http://www.html5canvastutorials.com/blog/2011/08/3d-parallax-trend/">
 <img src="applications.png" alt="" />
 The 3D Parallax Effect
 </a></div>
<div id="item"><a href="http://www.html5canvastutorials.com/blog/2011/08/insanely-html5/">
 <img src="folder.png" alt="" />
 New Stuff in HTML5 and CSS3
 </a></div>
<div id="item"><a href="http://www.html5canvastutorials.com/blog/2011/08/jquery-parallax-scroll/">
 <img src="folder.png" alt="" />
 3D Parallax Scroll in jQuery
 </a></div>
<div id="more"><!-- An icon, similar to before denoting a 'more' button -->
 <a href="http://www.html5canvastutorials.com/blog/">
 <img src="more.png" alt="" />
 83 More In Finder
 </a></div>
<div id="folder-icon"><!-- The folder which holds everything else, covering it up when its not hovered over. -->
 <img src="folder.png" alt="" />
 Hover Over Me!</div>
</div>

Here are the images I’m using for this. Don’t forget to download them and put them in the same folder as this file!

lion wallpapermore iconfolder icon

This is all the HTML we need to get this to work. It’s pretty simple, just a bunch of span’s and anchors, so hopefully you’ll be able to figure it out! Lets move onto the CSS.

Crafting our CSS

First of all I set the basic position of our object and the background. If you wanted to use this on a real webpage, you can very easily move it around by changing the position in the #position class.


<style type="text/css">

body {
	background: url("lion.jpg");
	overflow-x: hidden;
}

/* You will have to move the fan down manually (about 500px)
because of the position absolute, and I didn't
want  to  use Javascript.   However  the other
stuff can   be  changed   to  your liking,  as
regards positioning */

#position {
	position: relative;
	top: 470px;
	left: 100px;
	width: 500px;
	margin: 0px auto;
}

Then add some simple CSS to make everything look nice. This is all pretty basic stuff. One of the main problems I ran into is since we’re working off hovering over the main #folder div, sometimes tiny gaps would appear between the folders when they spanned out like the OSX Fan does. This would lead to the fanned out icons disappearing because we were no longer hovering over the #folder div. I fixed this by increasing padding-bottom or positioning the animated divs so they would overlap each other. If you are editing the file, keep this in mind.


/* Some simple CSS */
	
#folder:hover a {
	opacity: 1;
}
	
#folder-icon {
	position: relative; z-index: 5;
	padding: 15px 0 0 0;
}
#folder {
	display: inline-block;
	width: 270px;
}
	
#item, #more {
	display: inline-block;
	position: absolute;
	bottom: 0;
	left: 0;
	height: 48px;
}
	
#item {
	padding: 5px 20px 40px 0px;
}
	
#more {
	padding: 0 0 45px 10px !important;
}
	
a {
	text-decoration: none;
	opacity: 0;
}


/* This is to make the wording beside the icons nice */
#folder div span {
	position: relative;
	bottom: 17px;
	border: 2px solid rgba(0,0,0,0);
	left: 15px;
	color: #fff;
	background: rgba(0,0,0,0.5);
	border-radius: 15px;
	padding: 4px 8px;
	font-family: 'Myriad Pro', Helvetica, Arial, sans-serif;
	text-shadow: 0px 2px 2px rgba(0,0,0,0.1);
	font-weight: bold;
}
	

/* Just some tidying up and hover effects */
a:hover > span {	
	border: 2px solid #fff !important;
}

#more span {
	bottom: 40px !important;
	left: -5px !important;
}
	
#folder-icon span {
	opacity: 1 !important;
	bottom: 5px;
}

The animation is perhaps the most unfamiliar bit of this whole tutorial. Luckily for you I just wrote a tutorial on animations and transitions which you can find here, so go on over there if you want to learn the ins and outs of how a CSS animation actually works. For this tutorial, I’m just going to give you the source code.

	/* The float animation, excuse the odd numbers, mostly trial and error (Multiples for each browser) */
	@-webkit-keyframes item-1 { 100% { bottom: 67px; opacity: 1; -webkit-transform: rotate(1deg); } }
	@-webkit-keyframes item-2 { 100% { bottom: 137px; left: 5px; opacity: 1; -webkit-transform: rotate(3deg); } }
	@-webkit-keyframes item-3 { 100% { bottom: 205px; left: 12px; opacity: 1; -webkit-transform: rotate(5deg); } }
	@-webkit-keyframes item-4 { 100% { bottom: 273px; left: 22px; opacity: 1; -webkit-transform: rotate(7deg); } }
	@-webkit-keyframes item-5 { 100% { bottom: 340px; left: 37px; opacity: 1; -webkit-transform: rotate(9deg); } }
	@-webkit-keyframes item-6 { 100% { bottom: 427px; left: 42px; opacity: 1; -webkit-transform: rotate(11deg); } }
		
	/* Ugh, if only one property could be used! */
	@-ms-keyframes item-1 { 100% { bottom: 67px; left: 8px; opacity: 1; -ms-transform: rotate(1deg); } }
	@-ms-keyframes item-2 { 100% { bottom: 137px; left: 5px; opacity: 1; -ms-transform: rotate(3deg); } }
	@-ms-keyframes item-3 { 100% { bottom: 205px; left: 12px; opacity: 1; -ms-transform: rotate(5deg); } }
	@-ms-keyframes item-4 { 100% { bottom: 273px; left: 22px; opacity: 1; -ms-transform: rotate(7deg); } }
	@-ms-keyframes item-5 { 100% { bottom: 340px; left: 37px; opacity: 1; -ms-transform: rotate(9deg); } }
	@-ms-keyframes item-6 { 100% { bottom: 427px; left: 42px; opacity: 1; -ms-transform: rotate(11deg); } }
		
	
	@-moz-keyframes item-1 { 100% { bottom: 67px; left: 8px; opacity: 1; -moz-transform: rotate(1deg); } }
	@-moz-keyframes item-2 { 100% { bottom: 137px; left: 5px; opacity: 1; -moz-transform: rotate(3deg); } }
	@-moz-keyframes item-3 { 100% { bottom: 205px; left: 12px; opacity: 1; -moz-transform: rotate(5deg); } }
	@-moz-keyframes item-4 { 100% { bottom: 273px; left: 22px; opacity: 1; -moz-transform: rotate(7deg); } }
	@-moz-keyframes item-5 { 100% { bottom: 340px; left: 37px; opacity: 1; -moz-transform: rotate(9deg); } }
	@-moz-keyframes item-6 { 100% { bottom: 427px; left: 42px; opacity: 1; -moz-transform: rotate(11deg); } }
	
	/* Initiate the animations */
	#folder:hover > div:nth-of-type(1) { 
		-webkit-animation: item-1 0.5s forwards; 
		-ms-animation: item-1 0.5s forwards; 
		-moz-animation: item-1 0.5s forwards;
	}
	#folder:hover > div:nth-of-type(2) { 
		-webkit-animation: item-2 0.5s forwards; 
		-ms-animation: item-2 0.5s forwards;
		-moz-animation: item-2 0.5s forwards; 
	}
	#folder:hover > div:nth-of-type(3) {
		-webkit-animation: item-3 0.5s forwards; 
		-ms-animation: item-3 0.5s forwards; 
		-moz-animation: item-3 0.5s forwards; 
	}
	#folder:hover > div:nth-of-type(4) { 
		-webkit-animation: item-4 0.5s forwards; 
		-ms-animation: item-4 0.5s forwards; 
		-moz-animation: item-4 0.5s forwards; 
	}
	#folder:hover > div:nth-of-type(5) { 
		-webkit-animation: item-5 0.5s forwards; 
		-ms-animation: item-5 0.5s forwards; 
		-moz-animation: item-5 0.5s forwards; 
	}
	#folder:hover > div:nth-of-type(6) { 
		-webkit-animation: item-6 0.5s forwards; 
		-ms-animation: item-6 0.5s forwards; 
		-moz-animation: item-6 0.5s forwards; 
	}

</style>

There is a lot of code, but that’s because of the incompatibility between browsers. In the future, when animations are fully supported, we’ll be able to cut this code down by two thirds. All you need to know is that the animation works by moving the divs by a certain amount. We then apply the various animations we’ve setup to each div so we end up with a lovely animated effect as the divs come out of the main folder. The opacity is set to 1 because otherwise we end up with a bunch of unsightly folders (and text!) floating over one another, at the start.

After you put that all together in one file you should end up with the desired effect. If you’ve been confused this whole time as to what the desired effect should be, click on the demo button below! Otherwise you might consider downloading the source files and playing around.