Menu Transition In Effects

Alt Text

Introduction

It’s been a while since my last demo. This one here is something I thought of after seeing the surge in popularity with push in side menus. I’ve seen a couple websites use menu transition to animate the menu items as they appear. Here I will show a simple effect of making the menu links stack upwards. The second effect I created is a Metro inspired menu that stacks upwards but uses random delays to make it look unique every time.

Icons from FontAwesome

HTML Structure

The traditional menu is super simple with just a UL full of LI’s. The Metro style is a little more complex. My markup may be a bit messy because I use a UL within a LI within a UL. You can also determine if the cell takes up half or the full row.

<ul class="side-menu">
  <h2 class="title">Menu</h2>
  <li class="row">
    <ul>
      <li class="metro red half"><a href="#"><i class="fa fa-google"></i></a></li>
      <li class="metro light-blue"><a href="#"><i class="fa fa-twitter"></i></a></li>
    </ul>
  </li>
  <li class="row">
    <ul>
      <li class="metro blue half"><a href="#"><i class="fa fa-facebook"></i></a></li>
      <li class="metro green half"><a href="#"><i class="fa fa-android"></i></a></li>
    </ul>
  </li>
  <li class="row">
    <ul>
      <li class="metro pink half"><a href="#"><i class="fa fa-dribbble"></i></a></li>
      <li class="metro orange half"><a href="#"><i class="fa fa-github"></i></a></li>
    </ul>
  </li>
  <li class="row">
    <ul>
      <li class="metro light-blue full"><a href="#"><i class="fa fa-skype"></i></a></li>
    </ul>
  </li>
</ul>

CSS Styles

The css isn’t too complicated because most of this effect is achieved with jQuery. The css defines the structure, the hierarchy, the sizes, and the colors.

ul.side-menu {
  position: fixed;
  top: 0;
  right: -250px;
  width: 250px;
  height: 100%;
  background-color: #444;
  z-index: -1;

  -webkit-transition: right .3s;
  transition: right .3s;
}
  ul.side-menu.open {
    right: 0;
  }
  ul.side-menu li {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: 0 20px;
    text-align: left;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid #555;

    -webkit-transition: top .3s;
    transition: top .3s;
  }
  ul.side-menu li.row {
    border: 0;
    position: static;
    top: 0;
    height: 0;
    -webkit-transition: none;
    transition: none;
  }
    ul.side-menu li.metro {
      position: absolute;
      padding: 0;
      height: 125px;
      text-align: center;
      background-color: #CCC;
    }
      ul.side-menu li.metro.half { width: 50%; }
      ul.side-menu li.metro.full { width: 100%; }

    ul.side-menu h2.title {
      text-align: left;
      padding: 0 20px;
      position: relative;
      top: -60px;
      font-size: 23px;
      line-height: 60px;
      height: 60px;
      background-color: #555;

      -webkit-transition: top .3s;
      transition: top .3s;
    }
    ul.side-menu li a {
      display: block;
      font-size: 12px;
      padding: 0;
      margin: 0;
      height: inherit;
      line-height: inherit;
    }
      ul.side-menu li.metro a {
        margin: 42px 0;
        height: 40px;
        font-size: 40px;
      }

    /* Colors */
    ul.side-menu li.metro.blue { background-color: #5c84db; }
    ul.side-menu li.metro.light-blue { background-color: #2FC2EF; }
    ul.side-menu li.metro.purple { background-color: #a24fea; }

    ul.side-menu li.metro.red { background-color: #e54747; }
    ul.side-menu li.metro.pink { background-color: #ea4c89; }
    ul.side-menu li.metro.green { background-color: #85e500; }
    ul.side-menu li.metro.orange { background-color: #e28f00; }
    ul.side-menu li.metro.teal { background-color: #00e2e2; }

jQuery Menu Transition

This is the thing that makes it all work. it calculates the vertical height by using the jQuery function Index. It also calculates the delay using this. The Metro effect uses javascript’s random functions to make the delays random but still in order.

var menu_head = $('ul.side-menu h2.title').height();
var item_height = $('ul.side-menu li a').height();
// Untoggle menu on click outside of it
$(document).mouseup(function (e) {
  var container = $('ul.side-menu');
  if ((!container.is(e.target) && container.has(e.target).length === 0) && 
     (!($('a.menu-icon').is(e.target)) && $('a.menu-icon').has(e.target).length === 0)) {
    container.removeClass("in");
    $('body, ul.side-menu').removeClass("open");
  	$('ul.side-menu li').css("top", "100%");
    $('ul.side-menu h2').css("top", "-60px");
  }
});

$("a.menu-icon").click(function(e) {
  e.preventDefault();
  if ($('ul.side-menu, body').hasClass('open')) {
  	$('ul.side-menu').removeClass('open');
  	$('body').removeClass('open');

  	// Reset menu on close
  	$('ul.side-menu li').css("top", "100%");
    $('ul.side-menu h2').css("top", "-60px");
  }
  else {
    $('ul.side-menu').addClass('open');
    $('body').addClass('open');

    $('ul.side-menu h2').css("top", 0);
    $('ul.side-menu li').each(function() {
    	// Traditional Effect
    	if ($(this).hasClass('link')) {
    		var i = ($(this).index() - 1)
      	var fromTop = menu_head + (i * item_height);
      	var delayTime = 100 * i;
      	$(this).delay(delayTime).queue(function(){
	        $(this).css("top", fromTop);
	        $(this).dequeue();
	    	});
    	}
    	// Metro Effect
    	else if ($(this).hasClass('metro')) {
    		var row_i = ($(this).parent().parent().index() - 1); // Vertical Index
    		var col_i = $(this).index(); // Horizontal Index
    		var fromTop = menu_head + (row_i * 125);
				var fromLeft = col_i * 125;
				var delayTime = (row_i * 200) + Math.floor((Math.random() * 200) + 1);
				console.log(delayTime);
	      $(this).css("left", fromLeft);
				$(this).delay(delayTime).queue(function(){
	      	$(this).css("top", fromTop);
	        $(this).dequeue();
	    	});
    	}
    });
  }

});