Create a staggered animated menu with CSS

A nice and simple web development tutorial for you today. We are going to create a vertical navigation block, that could be used for such things as a table of contents menu, or slick dropdown menu for example. And utilising the power of power of CSS3’s transition property – we are going to make the menu items animated.

The demo of this tutorial can be found here.

Get a copy of jQuery

We are going to use using jQuery to toggle the menu item’s classes so go ahead and add a copy into your page.

<script
   src="https://code.jquery.com/jquery-1.12.4.min.js"
   integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
   crossorigin="anonymous">
</script>

Let’s create our toggle action

Now, let’s start by creating a toggle action that we can use to expand and minimise our navigation menu. This is just to see the menu in action.

<span id="toggle-menu">Toggle me</span>

Navigation markup

Now we create our navigation block with some menu items.

<nav id="primary-nav">
   <ul>
      <li><a href="">Home</a></li>
      <li><a href="">About</a></li>
      <li><a href="">Services</a></li>
      <li><a href="">Team</a></li>
      <li><a href="">Contact</a></li>
   </ul>
</nav>

Now we have something that looks like this

Styling our navigation block

Now we can start styling our navigation menu but first, let’s give our toggle action some breathing room above the menu.

span#toggle-menu {
	display: block;
	margin-bottom: 20px;
	cursor: pointer;
}

Now, let’s create our vertical menu.

nav#primary-nav {
   width: 300px; /* Choose whatever width you would like */
}
   nav#primary-nav li {
      list-style: none /* Remove the default bullet */
      display: block; /* Fills up the entire width of our parent nav */
      background: #de456b; /* Give each menu item a sleek background colour */
      margin: 0; /* We don't want any margins between items */
      border-bottom: 1px solid #fff; /* Give each menu item a white bottom border */
      width: 0; /* Initially set the menu item's width to be 0 */
      transition: width 500ms; /* Add a transition with a width property so when a menu item changes width, the animation activates with a 500 millisecond duration */
      overflow: hidden; /* Hide the menu item and text when the width is set to 0 */
   }
      nav#primary-nav a {
         color: #fff; /* Sets the link colour to white */
         padding: 10px; /* Give the link a bit of padding */
         display: /* Fills up the entire width of our parent list item */
      }

What our menu looks like so far

Hooking up our toggle action

Using jQuery’s toggleClass function, it’s a breeze to change class on click of our toggle span element.

The below code basically sits and waits until the toggle span element is clicked and either adds a is-active class or removes it, depending on if the menu is hidden or visible.

jQuery(document).ready(function()
{
   "use strict";
	
   var toggle = jQuery('span#toggle-menu');
   var menu_item = jQuery('nav#primary-nav li');
	
   toggle.click(function()
   {
      menu_item.toggleClass('is-active');
   });	
});

Now when we click our span toggle action, the menu is still hidden. What gives right? Well, something does actually happen in the fact that the is-active classes are being added! Next up, we need to animate them.

Animating the menu items

So when the is-active class is added to the menu items, we want to transition the width from 0% to 100%.

nav#primary-nav li.is-active {
   width: 100%;
}

Now if we try clicking on the toggle action now, we can see that the menu does slide open but we want to stagger each item so on to the final bit.

Staggering each menu item

To stagger each menu item, we are going to delay each of the 5 menu items by 100 milliseconds plus the previous item’s delay duration.

nav#primary-nav li:nth-child(1) {
   transition-delay: 100ms; /* Delay first item by 100 milliseconds */
}
nav#primary-nav li:nth-child(2) {
   transition-delay: 200ms; /* Delay second item by 200 milliseconds */
}
nav#primary-nav li:nth-child(3) {
   transition-delay: 300ms; /* Delay third item by 300 milliseconds */
}
nav#primary-nav li:nth-child(4) {
   transition-delay: 400ms; /* Delay fourth item by 400 milliseconds */
}
nav#primary-nav li:nth-child(5) {
   transition-delay: 500ms;/* Delay fifth item by 500 milliseconds */
}

Now we get a nice staggered effect.

You can reply to this post by tweeting to me