O'Reilly

Create Spinning, Fading Icons with CSS3 and MooTools

By on  

A goal of my latest blog redesign was to practice what I preached a bit more;  add a bit more subtle flair.  One of the ways I accomplished that was by using CSS3 animations to change the display of my profile icons (RSS, GitHub, etc.)  I didn't want to abandon CSS animations completely though;  I added a bit of MooTools to randomize the icon's initial display position and rotation.  Let me show you how to use CSS3 and MooTools to create dymanic, rotating elements.

The HTML

We'll use the standard, accessible, SEO-friendly HTML for link creation:

<div id="followIcons">
	<a href="http://feeds2.feedburner.com/Bludice" rel="nofollow" id="iconRSS">RSS Feed</a>
	<a href="http://twitter.com/davidwalshblog" rel="nofollow" id="iconTwitter">@davidwalshblog Twitter</a>
	<a href="http://github.com/darkwing" rel="nofollow" id="iconGitHub">@davidwalshblog Twitter</a>
	<a href="http://del.icio.us/dwizzlestar" rel="nofollow" id="iconDelicious">dwizzlestar de.licio.us</a>
	<a href="http://facebook.com/davidwalsh83" rel="nofollow" id="iconFacebook">David Walsh Facebook</a>
	<a href="http://linkedin.com/in/davidjameswalsh" rel="nofollow" id="iconLinkedIn">David Walsh LinkedIn</a>
	<a href="skype:davidwalsh83?chat" id="iconSkype">David Walsh Skype</a>
	<a href="mailto:[email protected]" id="iconMail">David Walsh Email</a>
	<a href="http://mootools.net/forge/profile/davidwalsh" rel="nofollow" id="iconForge">David Walsh MooTools Forge</a>
</div>

CSS will make these links pretty.

The CSS

The first part of the process is using standard CSS to move the text off screen and instead use the icons as background images for the link:

#followIcons a	{ 
	display:inline-block; 
	width:48px; 
	height:48px; 
	text-indent:-3000px; 
	background-position:0 0; 
	background-repeat:no-repeat; 
	z-index:2000; 
	overflow:hidden; 
	position:absolute;
}

Once we've done that time-tested practice, it's time to put a few initial CSS3 settings into place.  As you probably know, at this point all CSS transform properties are browser-specific, so our CSS will get a bit lengthy:

#followIcons a	{ 
	transition-duration: 0.8s;
	transition-property: transform;
}

The transition duration will be 0.8 seconds and transition property will be a basic transform.  You can change the transform duration to any duration you'd like.  Too fast or too slow will ruin the effect (that's what she said).

The MooTools JavaScript

The first part is randomly positioning each node/icon within the container.  It's important to know the container's width and height, then subtract the icon width and height from that to know the true area you can fit the icon into.  Nothing would be more lame than a piece of the icon hidden. The next step of the process is adding mouseenter and mouseleave events to make the images rotate and fade in during each respective event.

// "Globals" - Will make things compress mo-betta
var $random = function(x) { return Math.random() * x; };
var availableWidth = 200, availableHeight = 40;

// Find the appropriate prefix icon
var cssPrefix = false;
switch(Browser.name) {
	case "safari":
		cssPrefix = "webkit";
		break;
	case "chrome":
		cssPrefix = "webkit";
		break;
	case "firefox":
		cssPrefix = "moz";
		break;
	case "opera":
		cssPrefix = "o";
		break;
	case "ie":
		cssPrefix = "ms";
		break;
}

// The Icons
var icons = $$("#followIcons a");
// Apply opacity
var zIndex = 1000;

// Randomize each link
icons.each(function(element,index) {
	// Generate the random rotation amount
	var startDeg = $random(360);
	// Place the image at the default rotation and opacity
	var resetPlace = function() {
		element.fade(0.6).setStyle("-" + cssPrefix + "-transform","rotate(" + startDeg + "deg)");
	};
	// Randomly position the element
	element.set("style","top:" + $random(availableHeight) + "px; left:" + $random(availableWidth) + "px; z-index:" + zIndex);
	// Rotate the image initially
	resetPlace();
	// Add events
	element.addEvents({
		mouseenter: function() {
			element.fade(1).setStyle("z-index",++zIndex).setStyle("-" + cssPrefix + "-transform","rotate(0deg)");
		},
		mouseleave: resetPlace
	});
});

When the mouseenter event occurs, the rotation is animated to 0, no rotation.  When the mouse leaves the element, the element animates to its initial random rotation.  You'll also note that I've used opacity to add to the subtle effect.

And there you have it:  spinning, fading, animated elements.  What's the alternative?  Static, boring, traditional icons.   What do you think?  Too much?  Too little?  Share your ideas!

Track.js Error Reporting

Recent Features

  • Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

  • Create Spinning Rays with CSS3: Revisited

    Last December I wrote a blog post titled Create Spinning Rays with CSS3 Animations & JavaScript where I explained how easy it was to create a spinning rays animation with a bit of CSS and JavaScript. The post became quite popular so I...

Incredible Demos

Discussion

  1. Arian

    Why not test really for the prefix: http://jsfiddle.net/arian/sEVYY/

    besides prefix for ie is ms. Also to be future proof you should have something that will work when no prefix is needed anymore.

    You can use Number.random(0, 360) too btw, instead of your own random function.

    But it’s a nice effect for sure :)

  2. A quick update has been made for the purposes of Chrome.

  3. Matthew F

    Cute but it seems like it detracts from readability/usability…

  4. tampe125

    great!
    but sometimes icons overlap, is there a way to prevent that?

  5. Thank you so much for the codes! I’m in the process of installing them in my website as well.

    I don’t know if this is redundant, especially for you as a moo tools developer, but I would add in the instructions to add the

    … just for newcomers or peeps who stumble upon :)

  6. oopps the codes were snipped up… i meant to add in src=”https://ajax.googleapis.com/ajax/libs/mootools/1.3.0/mootools.js for javascript as well :)

  7. siddhesh

    is there anyway that the icons dont overlap please tell me how can that happen??

  8. Marcel Hadorn

    Very Nice, but this doesn’t work in IE9, although IE supports -ms-transform, and for example http://contrastrebellion.com did make use of this with jQuery. Wasn’t yet able to find the issue, if you do, please let us know.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Follow Redirects with cURL

    I love playing around with cURL. There's something about loading websites via command line that makes me feel like some type of smug hacker, just like tweeting from command line does. I recently cURL'd the Google homepage and saw the following: I found it weird that Google...

  • Developers Have WordPress, Amateurs Have Squarespace, Professional Designers Have the NEW Webydo!

    Web design platforms have traditionally come in one of two varieties. There are the solutions like WordPress and Drupal that are incredibly powerful, but an understanding of web development and coding is required to be able to use those platforms effectively. On the other side of the...

  • Chris Coyierâs Favorite CodePen Demos II

    Hey everyone! Before we get started, I just want to say it’s damn hard to pick this few favorites on CodePen. Not because, as a co-founder of CodePen, I feel like a dad picking which kid he likes best (RUDE). But because there is just so...

  • GSAP + SVG For Power Users: Motion Along A Path

    Now that the GreenSock API is picking up steam, there are many tutorials and Getting Started guides out there to provide good introductions to the library, not to mention GreenSock’s own Forum and Documentation. This article isn’t intended for beginners, but rather a...

  • Copy a Directory from Command Line

    Copying a directory for the sake of backup is something I do often, especially when I'm trying to figure out why something isn't working when I use an external library.  I'll copy the directory structure as a backup, mess around with the original source until I find a solution,...