Little Boxes Menu with jQuery

Today we will create a menu out of little boxes that animate randomly when a menu item is clicked. The clicked menu item expands and reveals a content area for […]

Today we will create a menu out of little boxes that animate randomly when a menu item is clicked. The clicked menu item expands and reveals a content area for some description or links. When the item is clicked again, the boxes will come back, reconstructing the initial background image.

Let’s get started!

Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.

The Markup

The HTML will be made up of a main container with div elements inside. Some of those will also contain a link and some content wrapper. All the elements will be positioned absolutely, so we will indicate their initial position as inline-style. We will also define the background image position for all the div elements containing one, so that the whole thing builds up a picture.

<div id="littleBoxes" class="littleBoxes">
	<div class="boxlink bg1" style="top:0px;left:0px;">
		<a href="">About</a>
		<div class="boxcontent">
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
				sed do eiusmod tempor incididunt ut labore et dolore magna
				aliqua. Ut enim ad minim veniam, quis nostrud exercitation
				ullamco laboris nisi ut aliquip ex ea commodo consequat.
			</p>
		</div>
	</div>
	<div class="bg5"
			style="background-position:-90px 0;top:0px;left:95px;"></div>
	<div class="bg5"
			style="background-position:-180px 0;top:0px;left:190px;"></div>
	<div class="bg5"
			style="background-position:-270px 0;top:0px;left:285px;"></div>

	<div class="bg5"
			style="background-position:0 -90px;top:95px;left:0px;"></div>
	<div class="boxlink bg2"
			style="top:95px;left:95px;">
		<a href="">Menu</a>
		<div class="boxcontent">
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
				sed do eiusmod tempor incididunt ut labore et dolore magna
				aliqua. Ut enim ad minim veniam, quis nostrud exercitation
				ullamco laboris nisi ut aliquip ex ea commodo consequat.
			</p>
		</div>
	</div>
	<div class="bg5"
			style="background-position:-180px -90px;top:95px;left:190px;"></div>
	<div class="bg5"
			style="background-position:-270px -90px;top:95px;left:285px;"></div>

	<div class="bg5"
			style="background-position:0 -180px;top:190px;left:0px;"></div>
	<div class="bg5"
			style="background-position:-90px -180px;top:190px;left:95px;"></div>
	<div class="boxlink bg3"
			style="top:190px;left:190px;">
		<a href="">Chef</a>
		<div class="boxcontent">
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
				sed do eiusmod tempor incididunt ut labore et dolore magna
				aliqua. Ut enim ad minim veniam, quis nostrud exercitation
				ullamco laboris nisi ut aliquip ex ea commodo consequat.
			</p>
		</div>
	</div>
	<div class="bg5"
			style="background-position:-270px -180px;top:190px;left:285px;"></div>

	<div class="bg5"
			style="background-position:0 -270px;top:285px;left:0px;"></div>
	<div class="bg5"
			style="background-position:-90px -270px;top:285px;left:95px;"></div>
	<div class="bg5"
			style="background-position:-180px -270px;top:285px;left:190px;"></div>
	<div class="boxlink bg4"
			style="top:285px;left:285px;">
		<a href="">Contact</a>
		<div class="boxcontent">
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
				sed do eiusmod tempor incididunt ut labore et dolore magna
				aliqua. Ut enim ad minim veniam, quis nostrud exercitation
				ullamco laboris nisi ut aliquip ex ea commodo consequat.
			</p>
		</div>
	</div>
</div>

The positioning values are calculated from the width and height of the boxes which is 90px plus its border (2px) and some margin (1px).

Let’s have a look at the style.

The CSS

Our main wrapper will be positioned relatively and centered vertically in the page:

.littleBoxes{
    width:350px;
    height:350px;
    margin:0 auto;
    position:relative;
}

The little boxes will be positioned absolutely and we will add some nice box shadow:

.littleBoxes > div{
    position:absolute;
    width:90px;
    height:90px;
    text-align:center;
    border:2px solid white;
    overflow:hidden;
    background-color:#f7f7f7;
    -moz-box-shadow:0px 0px 3px #555;
    -webkit-box-shadow:0px 0px 3px #555;
    box-shadow:0px 0px 3px #555;
    background-position:center center;
    z-index:999;
}

The link elements will have a repeated background image. We set the line height to the height of the box and add some neat box shadow that will only be revealed once the item is expanded:

.littleBoxes div a{
    text-transform:uppercase;
    font-size: 18px;
    font-weight:bold;
    letter-spacing:-1px;
    display:block;
    line-height:90px;
    text-decoration:none;
    color:#fff;
    background:#91EF4A url(../bgItem.png) repeat-x top left;
    outline:none;
    text-shadow:1px 1px 1px #888;
    -moz-box-shadow:1px 1px 3px #777;
    -webkit-box-shadow:1px 1px 3px #777;
    box-shadow:1px 1px 3px #777;
}

The description box will have the following style:

.littleBoxes div.boxcontent{
    width:334px;
    height:246px;
    text-align:left;
    padding:10px;
    font-size:16px;
    background-color:#f0f0f0;
    border:2px solid #fff;
    margin:10px 0px 0px 10px;
    text-shadow:1px 1px 1px #fff;
    -moz-box-shadow:1px 1px 3px #777;
    -webkit-box-shadow:1px 1px 3px #777;
    box-shadow:1px 1px 3px #777;
    opacity:0.8;
    display:none;
}

We need to set it to display:none since we only want to make it appear after the respective link box is expanded.

And finally, we define the background images in separate classes:

.bg1, .bg2, .bg3, .bg4{
    background-repeat:no-repeat;
}
.bg1{
    background-image:url(../images/1.jpg);
}
.bg2{
    background-image:url(../images/2.jpg);
}
.bg3{
    background-image:url(../images/3.jpg);
}
.bg4{
    background-image:url(../images/4.jpg);
}
.bg5{
    background-image:url(../images/5.jpg);
}

Like that, we just need to switch the class according to which link item we clicked.

Now, let’s add the magic:

The JavaScript

For the random “fly away” effect we need to save the initial positions of each box, so that we can bring them back to their positions once we click again on a menu item.

When we click on a menu item, we will randomly animate the positions of the boxes and make the current clicked box expand to the full width and height of the whole wrapper (or any other size). Also, we will make the description box appear.

If it’s the expanded menu item we are clicking on, we will contract the box again and bring back the other scattered boxes.

We will be using the jQuery easing plugin for the expansion and contraction of the boxes with the link elements.

$(function() {
	/* object to save the initial positions of each box */
	var divinfo = {"initial": []};
	/* index of the selected / clicked box */
	var current = -1;

	/* we save the index,top and left of each box */
	$('#littleBoxes > div').each(function(){
		var $this = $(this);
		var initial = {
					'index' : $this.index(),
					'top'     : $this.css('top'),
					'left'     : $this.css('left')
		};
		divinfo.initial.push(initial);
	});

	/* click event for the anchors inside of the boxes */
	$('#littleBoxes a').bind('click',function(e){
			var $this         = $(this);
			var $currentBox    = $this.parent();
			/* set a z-index lower than all the other boxes,
			to see the other boxes animation on the top*/
			$currentBox.css('z-index','1');

			/* if we are clicking on an expanded box: */
			if(current == $currentBox.index()){
				/* put it back (decrease width, height,
				and set the top and left back)
				the previous positions are saved in the divinfo obj*/
				$currentBox.stop().animate({
						'top'  : divinfo.initial[$currentBox.index()].top,
						'left' : divinfo.initial[$currentBox.index()].left,
						'width'  : '90px',
						'height' : '90px'
				},800,'easeOutBack').find('.boxcontent').fadeOut();

				$('#littleBoxes > div').not($currentBox).each(function(){
					var $ele         = $(this);
					var elemTop     = divinfo.initial[$ele.index()].top;
					var elemLeft     = divinfo.initial[$ele.index()].left;
					$ele.stop().show().animate({
						'top'         : elemTop,
						'left'        : elemLeft,
						'opacity'    : 1
					},800);
				});
				current = -1;
			}
			/* if we are clicking on a small box : */
			else{
				/* randomly animate all the other boxes.
				Math.floor(Math.random()*601) - 150 creates a random
				number between -150 and 450. This range is considering
				the initial lefts/tops of the elements. It's not the exact
				range, since we would have to calculate the range
				based on each one of the boxes. Anyway, it fits our needs...
				*/
				$('#littleBoxes > div').not($currentBox).each(function(){
					var $ele = $(this);
					$ele.stop().animate({
						'top' : (Math.floor(Math.random()*601) - 150) +'px',
						'left': (Math.floor(Math.random()*601) - 150) +'px',
						'opacity':0
					},800,function(){
						$(this).hide();
					});
				});

				/* expand the clicked one;
				also, fadeIn the content (boxcontent)
				*/
				var newwidth     = 379;
				var newheight     = 379;
				$currentBox.stop().animate({
					'top'     : '0px',
					'left'    : '0px',
					'width' : newwidth +'px',
					'height': newheight+'px'
				},800,'easeOutBack',function(){
					current = $currentBox.index();
					$(this).find('.boxcontent').fadeIn();
				});
			}
			e.preventDefault();
	});
});

And that’s it! I hope you enjoyed it and liked the tutorial!

Message from TestkingWe offer best quality testking 642-873 demos with certified testking 640-460 tutorials and testking 1z0-052 study guide to help you learn how to design different style little box with jQuery for commercial use.

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

๐Ÿ‘พ Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 32

Comments are closed.
  1. I like this simple style use of a good colour combination makes it highly effective

  2. I really adore jQuery. This looks so like Flash site, but it isn’t. Great effect

  3. Great effect ! This page needs a “Donate” area ๐Ÿ™‚ Keep up the great work !

  4. If I didn’t know it was jQuery, I would’ve instantly thought it was Flash. Good work!

  5. Great effet with javascript
    No effet without javascript

    But Good goood … good

  6. Nice tutorial. I love the animation of randomizing boxes’ positions and opacity. It’s really cool.

    Thanks for sharing.

  7. Great work!!! I never new jQuery was so totally awsome.

    Just wanted to know if we could make each link a # link. Which when opened in the browser directly, for eg: http://www.mysite.com/#contact would directly load the animation for that link.

  8. I would like to put a link in the boxcontent area but it doesn’t seem to work. Any ideas? Thanks.

  9. Awesome tutorial.

    Is it possible to create a regular link (in a navigation menu for example) to open the content area (boxcontent) (as if I clicked on one of the links in the box) and still have the animating effect happen?

    if so, how do you do it? thanks !

  10. I also think the links could be pointing to a real link so that the content could be loaded ajaxly

  11. @ Diane: just add a class (i.e. “myClass”) to each link which is right above the “boxcontent”, and then, in the script modify this bind function:
    $(‘#littleBoxes a’).bind
    to insert your class.
    Eg.: $(‘#littleBoxes a.myClass’).bind

    Don’t forget to add the changes to the css.
    Doing these you can add any links to the “boxcontent” and direct them where-ever you need.

    ๐Ÿ™‚

  12. @ Inadcod: Would you kindly elaborate a little more? I’ve got everything working now and want to add links as well however I’m not quite understanding your post.

    Thank you

  13. -> original: $(‘#littleBoxes a’).bind(‘click’,function(e){

    -> change to: $(‘#littleBoxes .hack’).bind(‘click’,function(e){

    +

    -> original: .littleBoxes div a{

    -> change to: .littleBoxes div .hack{

    … that makes hyperlinks working insinde the boxes ๐Ÿ™‚ pretty cool effect!

  14. Thank you for this tutorial.
    Iโ€™ve got everything working now and want to add links as well however Iโ€™m not quite understanding the previous posts about it. When I change it as said, it doesn’t work anymore. Can someone place the whole code (css and html) so I can figuere out what went wrong. Thanks a lot!

  15. good but same problem of hyperlink and the above post could not solve the problem

  16. @Moe: You have to add a class to each top link element inside the boxes. Taking the above example from the tutorial, something like:

    About

    This class needs to be added to each top link in each box, either the box WILL contain, or NOT, other links.
    Than, all you have to do is add this class to the bind function inside the script, like:
    $(‘#littleBoxes a.myClass’).bind(‘click’,function(e){
    20 var $this = $(this);
    21 var $currentBox = $this.parent();

    Sorry for the late answer ๐Ÿ™

  17. @rabab Did you work it out already? It seems simple but I still (newbie jquery) can’t get it to work. If so can you show me your css/html?

  18. Hi!

    I’m working with this code but in a different way (the code itself is fantastic, that’s why I’m using it, but my needs in my case are different).

    I’d like to click in a box and despite of going to a new box, just link a page of my site (huge for that tiny emerging box).

    So, I wouldn’t need the boxlink, just keep the effect of dispersion and then redirect to a custom page.

    Which part of the js code should I change without losing the effect and just go ahead with the link?

    Thank you! ๐Ÿ™‚

  19. I JUST MADE THE BEST WEBSITE IVE EVER MADE EVER.. THANKS TO YOU!!! THANK YOUUUUUUUUUU! <3333 SOOOO BEAUTIFUL!!! ๐Ÿ˜€ ๐Ÿ˜€

  20. just one thing though.. i tried putting links in the content and it somehow made the boxes disappear? and… is there a way to increase the size of it? thank you again!!

  21. Congratulations on the work really good .. Now I’m customizing the Little Boxes or Navigation Menu with jQuery and I wonder if can put links to another page. Or the effect does not allow link?