Submit your widget

jQuery small Boxes Menu

Created 14 years ago   Views 12630   downloads 2834    Author n/a
jQuery small Boxes Menu
View DemoDownload
128
Share |

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.

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);
}

 

 

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!