Powered By Blogger

lunes, 6 de agosto de 2012

Create a Sliding Navigation Menu with jQuery

Having a sliding navigation menu helps users to find the important pages of your website in a cool way. It is important to keep your navigation menu simple and user-friendly while keeping it attractive.

Consider a situation where you include your blog categories in a navigation menu. If you have a long category list, a drop down navigation menu will exceed the page height and the user might need to scroll to navigate to the last part of the menu. These small things are enough for a user to navigate away from your site.

To solve that, we are going to create a complete navigation menu using jQuery. I will explain how to compress large menus using sliding panels to keep the depth of your menu to a minimum level. Take a look at the demo before we get started. You can see that sub level menu items are hidden initially and displayed as sliding panels on click.

Demo | Download


Creating Main Menu Items

In most navigation menus, main items will be displayed initially and sub items are displayed when you hover on the main menu items. So let’s see how to create main menu items using an Unordered list.

  <ul id='header_nav'>      <li><img src="images/home-icon.png" /></li>      <li>About Us</li>        <li>Categories</li>      <li>Archive</li>      <li>Contact</li>      <li>Write For Us ?</li>  </ul>  

Styles for main menu items are given below.

  .level1{          background-color: #000000;          border-radius: 3px 3px 3px 3px;          color: #FFFFFF;          display: inline;          float: left;          margin: 0 5px;          padding: 14px 10px;          position: relative;          font-family: arial;          font-size: 13px;          border-top:1px solid #ababab;          border-left:1px solid #7e7e7e;          border-right:1px solid #6f6f6f;;          font-family: 'HelveticaNeueLT Com 65 Md';          height:12px;          background: rgb(158,158,158); /* Old browsers */          background: -moz-linear-gradient(top,  rgba(158,158,158,1) 0%, rgba(191,191,191,1) 1%, rgba(158,158,158,1) 1%, rgba(130,130,130,1) 3%, rgba(130,130,130,1) 49%, rgba(99,99,99,1) 100%); /* FF3.6+ */          background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(158,158,158,1)), color-stop(1%,rgba(191,191,191,1)), color-stop(1%,rgba(158,158,158,1)), color-stop(3%,rgba(130,130,130,1)), color-stop(49%,rgba(130,130,130,1)), color-stop(100%,rgba(99,99,99,1))); /* Chrome,Safari4+ */          background: -webkit-linear-gradient(top,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* Chrome10+,Safari5.1+ */          background: -o-linear-gradient(top,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* Opera 11.10+ */          background: -ms-linear-gradient(top,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* IE10+ */          background: linear-gradient(to bottom,  rgba(158,158,158,1) 0%,rgba(191,191,191,1) 1%,rgba(158,158,158,1) 1%,rgba(130,130,130,1) 3%,rgba(130,130,130,1) 49%,rgba(99,99,99,1) 100%); /* W3C */          filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e9e9e', endColorstr='#636363',GradientType=0 ); /* IE6-8 */      }  

I have defined a class called level1 for the main menu items. I have used gradient colors for the menu items. Gradient colors can be easily generated and customized using free online gradient generators.

Important thing here is that list items does not have a class called level1. I am assigning the class for each level dynamically using jQuery after the page is loaded. Following is the code for assigning the class to menu items based on the depth.

          $("#header_nav > li ").addClass("level1");          $("#header_nav  > li > ul > li ").addClass("level2");          $("#header_nav  > li > ul > li > ul > li ").addClass("level3");  
  • First line selects the immediate li items in header_nav element and adds class level1
  • Likewise we can assign classes level2 and level3 to the sub menu items using the above jQuery selector expressions.

Now our menu should look like the following screen.

Initial Menu Screen

Creating Sub Menu Items

Now we have main menu items with the styles applied. Lets see how we can create sub menu items using CSS and HTML. Consider the following code:

  <ul id='header_nav'>      <li><img src="images/home-icon.png" /></li>      <li>About Us</li>      <li>Categories          <ul>              <li><a>Coding</a></li>              <li><a>Freebies<span class="arrow-right"></span></a></li>              <li><a>Tutorial<span class="arrow-right"></span></a></li>              <li><a>Web Design</a></li>          </ul>      </li>      <li>Archive</li>      <li>Contact</li>      <li>Write For Us ?</li>  </ul>  
  • We have to create another unordered list inside the main menu item to display the sub menu items. I have created a link inside each sub menu item as shown above.
  • Also you can see span element with the class arrow-right. Freebies and Tutorial items are going to have another sub menu ( sliding menu) items.
  • So whenever you have a sub menu with another sub level, you have to use <span class=”arrow-right”></span> inside the link. This will show a small arrow to indicate that another sub level exists for the given menu.

The following code is used to style the level2 elements.

  #header_nav ul{          position:absolute;          padding:0;          left:-1px;          display:none;          margin-top: 20px;          font-family: 'HelveticaNeueLT Com 65 Md';        }        .level2 a{          padding: 14px 10px 10px;          display: block;          font-family: 'HelveticaNeueLT Com 65 Md';        }        .level2{          width:150px;          margin: 0;          border-radius:0px;          border-top:1px solid #000;          font-family: 'HelveticaNeueLT Com 65 Md';          color: #FFFFFF;          display: inline;          float: left;          font-family: arial;          font-size: 13px;          border-left:1px solid #7d7d7d;          border-right:1px solid #7d7d7d;;          background: #afafaf; /* Old browsers */          background: -moz-linear-gradient(top, #afafaf 0%, #7e7e7e 1%, #7a7a7a 38%, #747474 50%, #6b6b6b 77%, #686868 99%, #757575 100%); /* FF3.6+ */          background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#afafaf), color-stop(1%,#7e7e7e), color-stop(38%,#7a7a7a), color-stop(50%,#747474), color-stop(77%,#6b6b6b), color-stop(99%,#686868), color-stop(100%,#757575)); /* Chrome,Safari4+ */          background: -webkit-linear-gradient(top, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* Chrome10+,Safari5.1+ */          background: -o-linear-gradient(top, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* Opera 11.10+ */          background: -ms-linear-gradient(top, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* IE10+ */          background: linear-gradient(to bottom, #afafaf 0%,#7e7e7e 1%,#7a7a7a 38%,#747474 50%,#6b6b6b 77%,#686868 99%,#757575 100%); /* W3C */          filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#afafaf', endColorstr='#757575',GradientType=0 ); /* IE6-9 */      }    .arrow-right {      border-bottom: 5px solid transparent;      border-left: 5px solid #FCFCFC;      border-top: 5px solid transparent;      float: right;      height: 0;      margin-top: 3px;      width: 0;      margin-right: 10px;  }  
  • Initially, sub menus will be hidden. I have used display:none on #header_nav ul to make them hidden. First change it to display:block to get a quick look at how its positioned.
  • You can see the space between main menu item and sub menu item. I have used margin-top: 20px. The sub menu will overlap with the main menu if we don’t specify a margin. Remove it and see what happens.
  • The next important thing is position:absolute. Main menu items are positioned relatively, so we can position sub menus absolutely compared to the main menus. If you remove this sub menu items will align horizontally as main menu items. So we have to position it absolutely to get the vertical (dropdown) behavior.
  • Also we need to specify width for sub menu items in the level2 class. Otherwise each item will have its own width and will not have a great look. Change it according to your preference. I have defined it as 150px
  • Apart from the above, other styles in level2 class are used to improve the look and feel of sub menus. Now we are done with creating sub menus and change it back to display:none again.

Now our menu should look like the following screen.

Sub Menu Initial Display

Displaying Sub Menus on Hover

Sub menus are hidden initially. So in this section I am going to explain how to show them. In this section we’ll:

  • Display the main menu in different color on hover.
  • Fill the gap between main menu and sub menu on hover.
  • Show the hidden sub menus and hide the other sub menus.

I am going to use jQuery function called $(“.level1″).live(“hover”,function(){}) in this section. This function will be called each time you hover on the level1 menu item. I’ll explain the code inside this function using smaller sections. You can find the complete code inside the project files.

Lets get started.

              $(".level1").removeClass("main_menu_hover");              $(this).addClass("main_menu_hover");  
  • First thing we have to do is highlight the main menu items on hover. I am using a class called main_menu_hover to provide a different color.
  • Initially we remove main_menu_hover class from all the level1 items if it exists. Then we add the class to the hovered menu item using $(this).addClass method.
              var numberofChildren = $(this).find("> ul").children().length;                if(numberofChildren != 0){                  // Section 1                  $(".level1").removeClass("active_main_menu");                  $(this).addClass("active_main_menu");                    // Section 2                  $(".level1").find("ul").css("display","none");                  $(this).find(" > ul").css("display","block");                    // Section 3                  $(".level2").removeClass("active_first_element");                  $(".level2").removeClass("active_last_element");                  $(".level2").removeClass("active_only_element");                    // Section 4                  if(numberofChildren == 1){                      $(this).find("ul li:first").addClass("active_only_element");                  }else{                      $(this).find("ul li:first").addClass("active_first_element");                      $(this).find("ul li:last-child").addClass("active_last_element");                  }                    // Section 5                  $(".level2 a").removeClass("sub_active");                  $(".level2").removeClass("menu_hover");                }else{                  // Section 6                  $(".level1").find("ul").css("display","none");                  $(".level1").removeClass("active_main_menu");                }  
  • First we get the number of sub menu items for the currently hovered main menu.
  • If the main menu has sub items, we remove the class active_main_menu and add the class to the currently hovered element using Section 1 code. Initially there will not be any elements with active_main_menu class. Once you hover it will apply to the current item.
  • Apart from identifying the current element, active_main_menu class is used to fill the gap between main menu and sub menu. I’ll provide the CSS for this class in next section.
  • Section 2 – We have to hide all the displayed sub menus before showing the sub menu of current item. Then we display the current sub menu using $(this) element.
  • Section 3 – Code here is used to reset the classes on other elements which will be discussed next.
  • Section 4 – Some menus can have one sub menu and some can have more than one sub menu. So in this section if the menu has only one sub menu, we add the class active_only_element. Otherwise we add class active_first_element to the first item and active_first_element to the last item.
  • Above classes are used to display the first and last sub menu items in different styles than others.
  • Section 5 – This code is used to reset the classes of level2 sub menus once you hover on another main menu.
  • Section 6 – If the main menu does not have any sub menus, we rest the previously used sub menu classes using this code.

Following is the styes for the above section.

  .main_menu_hover{      background: #656565; /* Old browsers */      background: -moz-linear-gradient(top, #656565 0%, #676767 1%, #696969 38%, #747474 50%, #6c6c6c 77%, #676767 99%, #676767 100%); /* FF3.6+ */      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#656565), color-stop(1%,#676767), color-stop(38%,#696969), color-stop(50%,#747474), color-stop(77%,#6c6c6c), color-stop(99%,#676767), color-stop(100%,#676767)); /* Chrome,Safari4+ */      background: -webkit-linear-gradient(top, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* Chrome10+,Safari5.1+ */      background: -o-linear-gradient(top, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* Opera 11.10+ */      background: -ms-linear-gradient(top, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* IE10+ */      background: linear-gradient(to bottom, #656565 0%,#676767 1%,#696969 38%,#747474 50%,#6c6c6c 77%,#676767 99%,#676767 100%); /* W3C */      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#656565', endColorstr='#676767',GradientType=0 ); /* IE6-9 */    }    .active_main_menu{      height: 35px;  }    .active_first_element{      border-radius:2px 2px 0 0;      border-top:1px solid #000;      background: -moz-linear-gradient(center top , #6C6C6C, #575758) ;      background: -webkit-gradient(center top , #6C6C6C, #575758) ; /* Chrome,Safari4+ */      background: -webkit-linear-gradient(center top , #6C6C6C, #575758); /* Chrome10+,Safari5.1+ */      background: -o-linear-gradient(center top , #6C6C6C, #575758); /* Opera 11.10+ */      background: -ms-linear-gradient(center top , #6C6C6C, #575758); /* IE10+ */      background: linear-gradient(center top , #6C6C6C, #575758); /* W3C */    }    .active_last_element{      border-radius:0 0 2px 2px;      border-top:1px solid #000;    }  .active_only_element{      border-top:1px solid #000;      background: -moz-linear-gradient(center top , #6C6C6C, #575758) ;      background: -webkit-gradient(center top , #6C6C6C, #575758) ; /* Chrome,Safari4+ */      background: -webkit-linear-gradient(center top , #6C6C6C, #575758); /* Chrome10+,Safari5.1+ */      background: -o-linear-gradient(center top , #6C6C6C, #575758); /* Opera 11.10+ */      background: -ms-linear-gradient(center top , #6C6C6C, #575758); /* IE10+ */      background: linear-gradient(center top , #6C6C6C, #575758); /* W3C */      border-radius:2px;  }    

Add Hover Effects to Sub Menu

Once you hover on the sub menu items it should be highlighted in order to provide a better outlook. Lets see how to provide highlighting effects on hover.

          $(".level2 > a").live("hover",function(e){              $("li").removeClass("menu_hover");              $(this).parent().addClass("menu_hover");              e.preventDefault();          });  

The code above gets the immediate links of level2 (not links of level3) and removes the menu_hover class from previously applied elements and adds it to the current sub menu item.

  .menu_hover{      background: rgb(255,138,22); /* Old browsers */      /* IE9 SVG, needs conditional override of 'filter' to 'none' */      background: -moz-linear-gradient(top,  rgba(255,138,22,1) 0%, rgba(255,179,109,1) 1%, rgba(255,138,22,1) 3%, rgba(232,139,9,1) 40%, rgba(229,110,0,1) 82%, rgba(224,119,0,1) 97%); /* FF3.6+ */      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,138,22,1)), color-stop(1%,rgba(255,179,109,1)), color-stop(3%,rgba(255,138,22,1)), color-stop(40%,rgba(232,139,9,1)), color-stop(82%,rgba(229,110,0,1)), color-stop(97%,rgba(224,119,0,1))); /* Chrome,Safari4+ */      background: -webkit-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Chrome10+,Safari5.1+ */      background: -o-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Opera 11.10+ */      background: -ms-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* IE10+ */      background: linear-gradient(to bottom,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* W3C */      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff8a16', endColorstr='#e07700',GradientType=0 ); /* IE6-8 */        border-top:1px solid #000;      padding-bottom: 0px;    }  

Now we have both main menus and sub menus working perfectly. It should look like the screen below. Lets see how to create level3 sliding menus.

Sub Menu After Filling Gap

Creating Sliding Menu Panels

This is the most important part of this tutorial as it will hide the long menus and display as sliding panels on hover. This will decrease the size of your menu as well as provide interactivity for the user. Let’s build the sliding menu.

  <ul id='header_nav'>      <li><img src="images/home-icon.png" /></li>      <li>About Us</li>      <li>Categories          <ul>              <li><a>Coding</a></li>              <li><a>Freebies<span class="arrow-right"></span></a>                  <ul>                      <li><a>Icons<span class="items_num">5</span></a></li>                      <li><a>Templates<span class="items_num">10</span></a></li>                      <li><a>Fonts<span class="items_num">3</span></a></li>                  </ul>              </li>              <li><a>Tutorial<span class="arrow-right"></span></a></li>              <li><a>Web Design</a></li>          </ul>      </li>      <li>Archive</li>      <li>Contact</li>      <li>Write For Us ?</li>  </ul>  
  • We have to add another unordered list to get sliding menus. It will be added after the anchor tag as shown in the code above.
  • Inside list items we have a link with the level3 menu text.
  • Also we can use <span class=”items_num”>5</span> in case you want display a number of items inside the level3 menu item. This can be used to define the blog posts inside specific category in a real world scenario.
  #header_nav ul ul{      position: relative;      left: 0px;      margin-top: 0;      display:none;  }    .level3 a{      padding: 8px 10px;      display: block;  }  .level3{      background: #49494A;      border: none;      outline: none;      border-top: 1px solid #000;      color: #FFFFFF;      display: inline;      float: left;      font-family: arial;      font-size: 13px;      width: 150px;  }  
  • We have to position level3 items relatively to the level2 items as shown in #header_nav ul ul. Change position, left and margin-top and see what happens.
  • Then we define the styles for level3 menus. Make sure to keep the width as same as the level2 menu.

Sliding menus are hidden initially. Let’s move on to displaying and applying effects on sliding menus.

Display Sliding Menu

           $(".level2 a").live("click",function(){              $("li").removeClass("menu_hover");                if($(this).hasClass("sub_active")){                  $(this).removeClass("sub_active");                  $(".level2 > ul").slideUp();              }else{                  $(".level2 ul").slideUp();                  $(".level2 a").removeClass("sub_active");                  $(this).addClass("sub_active");                  $(this).parent().find("ul").slideDown();              }          });  
  • Initially we call a function on the click event of anchor tag in level2 element.
  • First we remove the menu_hover class from all the menu items.
  • Then we check whether class sub_active is available in the current level2 menu. This class is used to identify whether to slide the panel up or down. Element with sub_active class means it is displayed currently and we need to hide it by using slideup.
  • If the class already exists, we remove the class and calls the slideup function to hide the menu.
  • If it is not available, we remove the sub_active class from previous elements and adds it to current element. Also we hide previously opened menus and display the current menu using slidedown method.

Following is the styles for above section.

  .sub_active{      background: rgb(255,138,22); /* Old browsers */      background: -moz-linear-gradient(top,  rgba(255,138,22,1) 0%, rgba(255,179,109,1) 1%, rgba(255,138,22,1) 3%, rgba(232,139,9,1) 40%, rgba(229,110,0,1) 82%, rgba(224,119,0,1) 97%); /* FF3.6+ */      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,138,22,1)), color-stop(1%,rgba(255,179,109,1)), color-stop(3%,rgba(255,138,22,1)), color-stop(40%,rgba(232,139,9,1)), color-stop(82%,rgba(229,110,0,1)), color-stop(97%,rgba(224,119,0,1))); /* Chrome,Safari4+ */      background: -webkit-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Chrome10+,Safari5.1+ */      background: -o-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* Opera 11.10+ */      background: -ms-linear-gradient(top,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* IE10+ */      background: linear-gradient(to bottom,  rgba(255,138,22,1) 0%,rgba(255,179,109,1) 1%,rgba(255,138,22,1) 3%,rgba(232,139,9,1) 40%,rgba(229,110,0,1) 82%,rgba(224,119,0,1) 97%); /* W3C */        border-top:1px solid #ababab;      padding-bottom: 0px;    }  

Let’s take a look at our menu now using the screen below.

Sliding Panel Menu Display

Now we are coming to the final part of the tutorial. We need to apply hover effects to the sliding menu items and format and align the numbers properly. The following code is used to achieve this.

                  $(".level3 a").live("hover",function(){                      if(!($(this).parent().hasClass("accordian_element_hover"))){                          $(this).parent().removeClass("level3").addClass("accordian_element_hover");                      }                  });                    $(".accordian_element_hover a").live("hover",function(){                      $(this).parent().addClass("level3").removeClass("accordian_element_hover");                  });  

As we did earlier, we check for the existence of class called accordian_element_hover and add or remove it depending on the status of the element.

  .accordian_element_hover{      background: #2D2D2D;      width:150px;      border-top:1px solid #000;      color: #FFFFFF;      display: inline;      float: left;      font-family: arial;      font-size: 13px;  }    .accordian_element_hover a{      padding: 8px 10px;      display: block;  }    .items_num{      background: none repeat scroll 0 0 #636363;      border: 1px solid #000000;      border-radius: 2px 2px 2px 2px;      color: #FFFFFF;      float: right;      font-size: 11px;      height: 14px;      padding: 2px 0;      position: relative;      text-align: center;      top: -2px;      width: 25px;  }  

Finally we have a cool sliding navigation menu using jQuery effects as shown below.

Sliding Panel Menu Hover

Feel free to use it in your projects and provide your suggestions below!



No hay comentarios: