jQuery OS X Style Dock and Stack Navigation

“Outside the Box” Navigation with jQuery

Just about every website uses the regular navigation concepts we’re all used to. After awhile this can get pretty boring, especially for designers who thrive on creativity. While mimicking the OS X dock and stacks isn’t new, it’s certainly not common.


A few days ago, Jeffrey posted about a potential “outside the box” competition on ThemeForest to encourage authors to put on their creativity hats and design usable templates with “outside the box” creative designs. In this tutorial I’ll cover a few ways to do just that with OS X style docks and stacks navigation.

Sources and Credits

Before we get started, I want to give a shout out to a couple guys who came to the rescue when they heard my call for help on Twitter. Steve updated the stacks script by Harley from using jQuery 1.2.6 to use the current 1.3.2 release and Rey Bango from the jQuery team helped me fix a bug. They both jumped to the task within a couple minutes of my cry for help via Twitter. Thanks a ton guys! *Round of applause* :-D

Dock and Stack Preview

Original Sources

Quick Notes

These scripts rely on jQuery 1.3.2. The examples shown are compatible with all major browsers including IE6 and are easy to ensure graceful degrading if JavaScript is off or disabled.

jQuery OS X Dock #1 (Horizontal)

The first dock we’ll build uses the jQuery Fisheye Menu plugin mentioned above. It’s pretty lightweight (~7kb with dependencies) but the main reason I wanted to use this one was because it’s incredibly smooth, no stuttering. View Demo.

jQuery Fisheye Menu Dock

As you can see in the demo, it’s incredibly smooth and responsive. The downside is that you can’t use fixed positioning with it if the page needs to scroll as it will break. If you don’t need it fixed within the browser window then it works great.

This is a great example of “outside the box” concepts in websites and provides an interactive and fun interface.

Required files (I’ve combined the Fisheye plugin and iutil.js in the demo files).

  • jQuery 1.3.2
  • Interface: Fisheye Menu plugin
  • Interface: iutil.js (dependency)

The HTML

We’ll wrap our images and titles in links and place them within a containing div. Then we’ll wrap it all in another containing div for it to function properly.


Notice that I’ve placed the titles in span tags so we can style them as well as allow the plugin to hide/show them as necessary.

The CSS

With CSS we’ll position the dock where we want it on the page. We can’t use fixed positioning with this plugin or it won’t function properly.

.dock-container { position: relative; top: -8px; height: 50px; padding-left: 20px; }
a.dock-item { display: block; width: 50px; position: absolute; bottom: 0; text-align: center; text-decoration: none; color: #333; }
.dock-item span { display: none; padding-left: 20px; }
.dock-item img { border: 0; margin: 5px 10px 0px; width: 100%; }

I’ve also placed a little extra CSS in the head of the page below the CSS included above. I wrapped it in noscript tags in case a visitor doesn’t have JavaScript enabled or available, it will still be a usable navigation. I should point out that this will not validate because the noscript tag isn’t valid in the head section, even though it works in all the current browsers. ;-)

#dock { top: -32px; }
a.dock-item { position: relative; float: left; margin-right: 10px; }
.dock-item span { display: block; }

The JavaScript

We’ll bring in our JavaScript files now starting with jQuery 1.3.2. The fisheye-iutil.min.js file is the combination of the Fisheye plugin and its dependent iutil.js file. We’ll create the last file and put our JavaScript necessary to initialize the dock in it.

%MINIFYHTML0e4ba44a62d40155d798606acceb52069%

Now we’ll initialize the dock once the page loads. You can use several plugin options to customize the dock as you need for positioning and functionality. You can view the documentation by visiting the site listed under sources for the Fisheye plugin.

$(function () { 
	// Dock initialize
	$('#dock').Fisheye(
		{
			maxWidth: 30,
			items: 'a',
			itemsText: 'span',
			container: '.dock-container',
			itemWidth: 50,
			proximity: 60,
			alignment : 'left',
			valign: 'bottom',
			halign : 'center'
		}
	);
});

That’s all there is to it! :-D

jQuery jqDock

jQuery OS X Dock #2 (Vertical)

The horizontal dock was easy and definitely a neat idea to use on websites. They’re probably the most common type used across the web currently so let’s try something different. We could get a little more “outside the box” if we did a vertical dock navigation.

This dock relies on the jqDock jQuery plugin. It’s approximately 10kb in size, so it’s a few kb larger than the previous version but that’s not much. The disadvantage to this plugin is that it’s not quite as smooth as the Fisheye plugin dock, although it’s still very fluid and certainly usable. This plugin also doesn’t have issues with fixed positioning. View Demo.

The HTML

We’ll put our images in an unordered list and wrap them in links. As with the last plugin, we’ll wrap everything within a containing div. When we initialize the plugin we’ll use the “ul” here.

  • Home
  • Contact
  • portfolio
  • music
  • video
  • history
  • calendar
  • links
  • rss
  • rss

You’ll notice on this dock we don’t have titles wrapped in span tags. Instead, this plugin will look at the “title” tag set for each image and create the titles that way (if enabled in the plugin options). This makes the markup a little simpler but it also makes the titles a little less customizable.

The CSS

We position the dock on the left side (can be either side) using fixed positioning. We’ll give it a little space between itself and the top of the browser window for aesthetics and so the icons don’t disappear when enlarged.

#dockContainer { position: fixed; top: 60px; left: 6px; }
#jqDock { position: relative; bottom: 48px; }
.jqDockLabel { background: #333; color: #fff; padding: 3px 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; }

To style the titles we can use the “.jqDockLabel” class. We also won’t need to include any extra styles for it to still be usable with JavaScript disabled. It may not be very pretty but it’s functional.

The JavaScript

We’ll bring in the jQuery library just like the previous dock as well as the plugin.

	

We initialize the dock and set a few options to customize it. You can read the documentation on these settings by visiting the site listed under sources at the beginning of the tutorial for jqDock. What I want to point out here though is the duration option. This is the time for magnification animation in milliseconds. It’s nice to be able to change the duration speed but it seems to get a little stuttery, which is something I hate.

$(function(){
	var jqDockOpts = {align: 'left', duration: 200, labels: 'tc', size: 48, distance: 85};
	$('#jqDock').jqDock(jqDockOpts);
});

You can easily change the positioning of the dock and labels as well as the initial size of the icons and a few other options. What I didn’t like about this plugin is that it magnifies to the full size of the icon. The previous plugin gives you the ability to change the size it magnifies to. That’s all there is to it!

jQuery OS X Stacks Example

jQuery OS X Stack and Drop Stack

This is probably my favorite navigation style out of the three shown in this tutorial. It’s super lightweight (~1kb) and is a really creative “outside the box” method of navigation for a website. It might be a little awkward having the navigation in the bottom right or left of the browser window but it would certainly be creative and save lots of space. View Demo.

While writing this, I realized there are probably many people that won’t like their navigation at the bottom of the page so I took a couple extra minutes and added a drop-down stack to the example files. This way the navigation springs out from top to bottom so it can now be used at the top of pages.
View Demo.

The HTML

The HTML is just as simple as the two dock examples. We’ll place everything in a containing div and place all our images and titles, which are wrapped in links, within an unordered list.


Notice that I’ve placed an image before the unordered list. This is the basket image that the rest of the icons will be stacked behind.

The CSS

We’ll position the main container and make sure the basket image has a higher z-index than the unordered list so everything stacks behind it. Also notice that I’ve given the basket image 35px of padding. This prevents the icons behind the basket from being clicked since the basket image is shorter than the icons. If you change the basket icon to something taller then you’ll need to also change the padding.

.stack { position: fixed; bottom: 28px; right: 40px; }
.stack > img { position: relative; cursor: pointer; padding-top: 35px; z-index: 2; }
.stack ul { list-style: none; position: absolute; top: 5px; cursor: pointer; z-index: 1; }
.stack ul li { position: absolute; }
.stack ul li img { border: 0; }
.stack ul li span { display: none; }
.stack .openStack li span { 
	font-family: "Lucida Grande", Lucida, Verdana, sans-serif;
	display:block;
	height: 14px;
	position:absolute;
	top: 17px;
	right:60px;
	line-height: 14px;
	border: 0;
	background-color:#000;
	padding: 3px 10px;
	border-radius: 10px;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	color: #fcfcfc;
	text-align: center;
	text-shadow: #000 1px 1px 1px;
	opacity: .85;
	filter: alpha(opacity = 85);
}

/* IE Fixes */
.stack { _position: absolute; }
.stack ul { _z-index:-1; _top:-15px; }
.stack ul li { *right:5px; }

The titles wrapped in span tags are set to display:none so they’ll be hidden when the page loads.

The JavaScript

We’ll place the JavaScript in its own file since it’s more than a couple lines. When the image outside the unordered list (the basket) is clicked, it uses jQuery’s toggle function to animate the the list items and set their position based on the horizontal starting point + .75px then multiplied by 2. This gives us the nice curved spring action of the list items.

You could change the .75px or the multiplier (2) to customize how much it curves.

$(function () { 
	// Stack initialize
	var openspeed = 300;
	var closespeed = 300;
	$('.stack>img').toggle(function(){
		var vertical = 0;
		var horizontal = 0;
		var $el=$(this);
		$el.next().children().each(function(){
			$(this).animate({top: '-' + vertical + 'px', left: horizontal + 'px'}, openspeed);
			vertical = vertical + 55;
			horizontal = (horizontal+.75)*2;
		});
		$el.next().animate({top: '-50px', left: '10px'}, openspeed).addClass('openStack')
		   .find('li a>img').animate({width: '50px', marginLeft: '9px'}, openspeed);
		$el.animate({paddingTop: '0'});
	}, function(){
		//reverse above
		var $el=$(this);
		$el.next().removeClass('openStack').children('li').animate({top: '55px', left: '-10px'}, closespeed);
		$el.next().find('li a>img').animate({width: '79px', marginLeft: '0'}, closespeed);
		$el.animate({paddingTop: '35'});
	});
	
	// Stacks additional animation
	$('.stack li a').hover(function(){
		$("img",this).animate({width: '56px'}, 100);
		$("span",this).animate({marginRight: '30px'});
	},function(){
		$("img",this).animate({width: '50px'}, 100);
		$("span",this).animate({marginRight: '0'});
	});
});

Then when the user clicks the basket image again it runs the next function which reverses what we just did. I then added some additional animation to the list items and their titles to give them a little more user feedback, which of course can easily be removed.

And there you have it! A simple and flexible OS X style stack navigation for your website. :-D This script is also in the process of being converted into an easier to use plugin so keep an eye out for that.

Final Thoughts

Hopefully these examples will give you some ideas to be creative and break out of the mold when designing your next website or template. As you can see, jQuery is a powerful library that makes it easy to make our ideas a reality. With a potential upcoming competition based on “outside the box” designs, you might get started on some ideas to submit to ThemeForest. If you haven’t submitted files before, it’s very easy and can definitely be well worth your time! :-)

I want to thank Rey (from the jQuery team) and Steve for answering my call for help on Twitter so quickly. This is a prime example of how useful Twitter can be for designers and developers. If you aren’t following Theme Forest or Nettuts on Twitter yet, now is a good time to do that. They’re both websites with a ton of fantastic information. You can also follow me on Twitter if you’d like.


Tags: jQuery
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://vivalacollege.com Kevin Urrutia

    Very nice i am going to try this

  • http://myfacefriends.com Myfacefriends

    very useful thanks again guys!

  • http://www.datamouse.biz DataMouse

    How cool is that effect!?
    Awesome

  • http://www.stephen-ainsworth.co.uk Stephen Ainsworth

    Although i’m not a fan of mimicing operating systems, i’m sure these navigation techniques will come in handy.

    Thanks!

  • b00m

    I luv jQuery! Tnx for sharing…worship!

  • http://threepixeldrift.co.cc Taylor Satula

    Very cool, much more seamless than the old one that harley alexander did.
    His was very cool though

  • http://nickd.info NickD

    Considering these are all based on existing navigation techniques – I wouldn’t really consider them ‘outside’ the box. Good write up’s none-the-less.

  • http://hiddencss.com Daniel Groves

    Absolutely loving it… already getting ideas for future designs!

  • Jerichvc

    i say its playful :D

  • http://www.diinote.com Greg

    awesome effects!

  • http://www.quizzpot.com crysfel

    hahahahaha… funny :D i like it, i agree with “Jerichvc”, its playful

  • http://www.cooltricksntips.com Rahul Jadhav

    Thats awesome stuff. One of the best things to show your links

  • Joe

    Awesome dude, keep up.

  • http://www.freshclickmedia.com Shane

    I like the stack and drop effect – very nice. I’m wondering where it could be used in a real-world situation.

    • http://laminbarrow.com Lamin Barrow

      I was also wondering where an effect like this might fit. It may be useful in a new ground breaking go and have fun type of website. :D

    • w1sh

      Think about that top-right basket. Notice how it’s icons drop out of it in directions of their own?

      You could do something like this for a portfolio where your main links dropdown into a brainstorm effect.

      Bah, I’m retardedly useless when it comes to explaining things.

    • Justin

      I could totally see a shopping cart with your selected items doing this. Click on it to review what you’ve decided to purchase. Grab one and toss it out. Etc…

  • http://www.mogillmedia.com Mike

    Seriously cool — thanks guys!

  • Julien

    The Stack is really great :)
    Btw, you should maybe add the .stop() function before to animate img & span, to avoid accumulation of animation.

  • EllisGL

    It double bounces when you come up from the bottom.

    • http://www.stupidsucks.com Jarel Remick
      Author

      Sean O recommended using jQuery’s stop() to fix this.

      Here’s the new animation code with this implemented. http://pastie.org/520632

  • Paul

    Wow…this is amazing!

  • http://www.larishteriastudio.com rishteria

    Really nice ;)

  • Koka Koala

    cool

  • http://labs.dariux.com Dario Gutierrez

    Sure very nice effects navigation. I’m going to try this.

  • http://matheleo.de matheleo

    Really great tut, but one thing:
    with the stacks, I’d change the horizontal offset to:
    >> horizontal = horizontal*1.4 + 2.4
    That’s much closer to Leopard’s stacks ;-) And your version drifts to right too fast for more items. You’ll have to shift it to the left, so that everything fits.

  • http://deconstructioncode.blogspot.com/ choen

    thanks for sharing…. i love it…

  • http://www.sean-o.com Sean O

    I recommend the technique described here:
    http://www.learningjquery.com/2009/01/quick-tip-prevent-animation-queue-buildup
    to prevent animation queue buildup on the corner demos.

    (roll over the icons a few times to see the issue)

  • http://www.stupidsucks.com Jarel Remick
    Author

    Thanks for the comments everyone! :-)

    @Sean O – Thanks for the recommendation. :-D

    I’ve implemented Sean O’s recommended fix (should have thought of it at time of writing) and here’s the animation code with jQuery’s stop() implemented.

    http://pastie.org/520632

  • Dj

    Once upon a time, when dinosaurs roamed the land, I remember an “outside the box” scheme of navigating computer menu’s which displayed each topic in a horizontal row and required the user to click on the topic which would *then* display another vertical row of options to click. Like “star wars” it was a quantum leap from what we otherwise had; *but* was very non-intuitive and drove us all nuts until someone devised a “drop-down” menu triggered by simply “tabbing” to the category or subsequently by merely *”hovering”* over it. What an idea who’s time had come!

    The basket, a great idea in an of itself, brings back unhappy memories of dinosaurs to me. Clicking to activate a menu is NOT intuitive in the current culture (without clunky “click me” instructions). Is there such a thing as a jQuery “hover-select” drop-down menu being activated from within another “hover-select?” I.E. could hovering over the basket cause it to expand slightly and eject the secondary “drop-up” menu which would then be navigable by hovering as well? That would be much more intuitive, as it is currently how most drop-down, nav-bars work.

    • http://www.stupidsucks.com Jarel Remick
      Author

      Yes, this is absolutely possible with jQuery (or just javascript). The point here is that many really cool ideas are possible with javascript.

      Also, the stacks navigation idea may not work for you but might work for someone else. Navigations on todays websites take up a fairly significant amount of space and for certain types of websites like blogs, they aren’t used that often. So why not create something creative and space saving like a stacks navigation interface? Remember too that this doesn’t have to be navigation, this can be applied to all sorts of ideas. Information blurbs, photo stacks, etc.

  • sam

    Pretty celver, but it looks very Mickey Mouse to me, almost as bad as the trailing javascript stuff on mouse movements…lol

  • http://kwaa.crownz.info/ Kwaa

    Those stacks are awesome, thanks for another great tutorial!

  • http://gfxcraft.eu Michael

    WOW! awesome effect :) definetly will try to use this :>

    thanks

  • Benjamin

    You need to change

    $(‘.stack li a’).hover(function(){
    $(“img”,this).animate({width: ’56px’}, 100);
    $(“span”,this).animate({marginRight: ’30px’});
    },function(){
    $(“img”,this).animate({width: ’50px’}, 100);
    $(“span”,this).animate({marginRight: ’0′});
    });

    to

    $(‘.stack li a’).hover(function(){
    $(“img”,this).stop().animate({width: ’56px’}, 100);
    $(“span”,this).stop().animate({marginRight: ’30px’});
    },function(){
    $(“img”,this).stop().animate({width: ’50px’}, 100);
    $(“span”,this).stop().animate({marginRight: ’0′});
    });

    then the stack will stop dancing

    • http://www.stupidsucks.com Jarel Remick
      Author

      Yup, listed above and posted at pastie.org – http://pastie.org/520632 ;-)

      • Benjamin

        I frown on links! ;) jk sorry about the dub post

  • http://firedartonline.com/ FireDart

    Saw the same thing here:
    http://www.wizzud.com/jqDock/

    But you actually explain how to do it!

    Thanks!

  • http://gomobile.com.ar/ Zim

    Amazing… I’ll try to pull it into the next version of my blog’s theme :D

  • http://www.jhondoe.info Jhon Doe

    cool

  • chad

    Pretty cool. One thing to note is that some of the effects do not gratefully fail, leaving your user with a menu that is frustrating.

    • http://www.stupidsucks.com Jarel Remick
      Author

      The examples here are still usable without javascript. They might not be pretty but they work. With a little extra work, they could easily be made to look pretty even without javascript. :-)

  • deedee

    This is what I’ve been looking for! Thankz!

  • http://www.webcoursesbangkok.com Carl – Web Courses Bangkok Instructor

    THing is, it would take a equally sexy design to make the navigation feel at home…I better get started :)

  • http://www.jdandco.co.uk Jacob Lee

    I agree with chad, but things like that aren’t too hard to fix, and it is a tutorial for learning, not a complete script.

    Regardless, the dock isn’t a new thing, but the bin/bucket thing actually is a nice idea, could be useful on some of the more extensive admin panels.

  • Devin Rajaram

    I was going to use thing for my template for the competition on themeforest.

  • http://www.netforj.com Julius

    Nice animation. great work man.

  • http://tuvidaloca.net Rata

    ¡Chulo!
    I’m going to try this in autumn, the days are getting shorter already ;)

    Kind regards
    Rata

  • http://www.seventhfury.com Matthew Johnson

    This. Is. Awesome.

  • http://www.webangel78.com webangel78

    Perfect animated navigation. jQuery is a great framework!

  • http://www.nampblog.com Vikram

    Hi looks interesting to me. How can i add/use this with by Blogger based blog. Can anybody help me out with the same – vikramdeo[at]nampblog[dot]com

  • http://www.imblog.info Muhammad Adnan

    very nice ,

  • http://modechecker.de/ George Gina Lucy

    It’s not perfect yet, but the idea is brilliant!

  • grrrrrrr8

    One word…. sweeeeeeeeeeeeeeeeeeeeeeet!!!

  • wayno007

    Very cool. Thanks for the tut.

  • http://www.crearedesign.co.uk Martyn Web

    I would love to add these to a site, my only concern is whether people with no experience of a mac would realise the leopard dock was a navigation. It might help if on the roll over the icons automatically popped up.

    Anyway it looks great regardless…

  • http://www.e11world.com e11world

    I like the stack effect.. nice one! I noticed the bottom right one wasn’t working though.

  • J