JSFiddle - React, Tailwind, and code Playground

css3 animated, responsive navigation menu (with submenu)

by Jennifer Perrin

HTML

<nav role="navigation" class="nav">
  
  <a class="menu-toggle" href="#head-nav">
    <span aria-hidden="true" class="icon-menu"></span><span class="menu-toggle-text"> menu</span>
  </a>
	
  <ul id="main-menu" class="top-nav menu clearfix">
    <li class="menu-item">
      <a href="http://codepen.io">Home</a>
    </li>
    <li class="menu-item">
      <a href="http://codepen.io">About</a>
    </li>
    <li class="menu-item">
      <a href="http://codepen.io">Archives</a>
    </li>
    <li class="menu-item">
      <a href="http://codepen.io">Categories</a>
      <ul class="sub-menu">
        <li class="menu-item">
          <a href="http://codepen.io">Reading</a>
        </li>
        <li class="menu-item">
          <a href="http://codepen.io">Writing</a>
        </li>
        <li class="menu-item">
          <a href="http://codepen.io">Arithmatic</a>
        </li>
        <li class="menu-item">
          <a href="http://codepen.io">Something Long</a>
        </li>
        <li class="menu-item">
          <a href="http://codepen.io">Something Else</a>
        </li>
      </ul>
    </li>
    <li class="menu-item">
      <a href="http://codepen.io">Contact</a>
    </li>
  </ul>
  
</nav>

CSS

@import url(http://fonts.googleapis.com/css?family=Quattrocento+Sans);
/****
SETUP
****/
@font-face {
  font-family: "symbolset";
  src: url(http://tedworthandoscar.co.uk/demos/fonts/ss-standard.eot);
  src: url(http://tedworthandoscar.co.uk/demos/fonts/ss-standard.eot?#iefix) format('eot'), url(http://tedworthandoscar.co.uk/demos/fonts/ss-standard.woff) format('woff'), url(http://tedworthandoscar.co.uk/demos/fonts/ss-standard.ttf) format('truetype'), url(http://tedworthandoscar.co.uk/demos/fonts/ss-standard.svg) format('svg');
}

[class^="icon-"]:before, [class*=" icon-"]:before {
  font-family: 'symbolset';
  font-style: normal;
  speak: none;
  font-weight: normal;
  vertical-align: top;
}

.icon-menu:before {
  content: "\eD50";
}

/************
THE REAL DEAL
************/
body {
  background: #ddc;
    margin: 0;
  font-family: 'Quattrocento Sans', Helmet, Freesans, Tahoma, Geneva, sans-serif;
}

a {
  -webkit-transition: color 800ms ease-in-out, background 800ms ease-in-out;
  -moz-transition: color 800ms ease-in-out, background 800ms ease-in-out;
  -o-transition: color 800ms ease-in-out, background 800ms ease-in-out;
  transition: color 800ms ease-in-out, background 800ms ease-in-out;
}

.nav {
  padding: 0;
  font-size: 1em;
  letter-spacing: 0.1em;
  text-align: center;
}
.nav .menu-toggle {
  position: relative;
  z-index: 2;
  display: block;
  margin: 0;
  padding: 0.5em 0;
  background-color: #ddc;
  text-decoration: none;
  text-align: center;
  font-size: 1.4em;
  color: #333333;
}
.nav .menu-toggle:hover, .nav .menu-toggle:focus {
  color: #eeeeee;
  background-color: #2e2e2e;
}
.nav .menu-toggle-text {
  font-size: 0.55em;
  display: block;
}
.no-js .nav .menu-toggle {
  display: none;
}
.nav .expanded-menu-toggle {
  color: #eeeeaa;
  background-color: #2e2e2e;
}
.no-fontface .nav .icon-menu:before {
  display: none;
}

/* .menu is visually hidden by default */
.menu {
  position: relative;
  z-index: 1;
  background-color: #333333;
  border:...

JavaScript

/*
Responsive nav menu with sub menus on larger screens.

built using very limited amount of js (javascript adds a couple of css classes) and to deal with an unknown number of menu items (used in several WordPress themes).

many further enhancements could easily be made (for example I normally include js to allow keyboard focus to automatically expand the collapsed menus) outside the scope of this demo.

The CSS could do with a bit of a clean up at the moment and the styling has intentionally been left very basic for this demo but the key points should still be clear!
*/

/**********
MOBILE MENU
**********/
$('.menu-toggle').click(function(e){
  //click event for left clicks only! http://www.jacklmoore.com/notes/click-events
  if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey)) {
    e.preventDefault();
    if($(this).parent().find('.menu').hasClass('expanded-mobile-menu')){
      $(this).removeClass('expanded-menu-toggle').parent().removeClass('nav-expanded').find('.menu').removeClass('expanded-mobile-menu');
    }else{
      $(this).addClass('expanded-menu-toggle').parent().addClass('nav-expanded').find('.menu').addClass('expanded-mobile-menu');
    }
  }
});