back to top
shopping basket

View your basket

Photo scanning service

What our customers are saying:

The picture on the front of the discs, of our two young daughters, was an amazing surprise for us.

Read more...

Responsive Dropdown Navigation with jQuery and CSS

Responsive Dropdown Navigation with jQuery and CSS

PiciScan Web Design Blog RSS Feed

Posted on: Thursday, 5 February 2015

Whether you are creating a responsive website from scratch or retro-fitting a non-responsive site, one of the hardest things to get right can be the navigation; especially if you want to make use of dropdown sub menus. As I browse the internet, I occasionally come across sites that have not been designed with touch in mind. The parent menu item is sometimes a link and it is something of a challenge to navigate to any of the child items in the dropdown list, or even get the dropdown to appear at all.

The method I have outlined below functions well across all devices and none of the parent menu items are links. If you want to see a live example of this menu, then just take a look at this very website on any device size you wish. On desktop or a large enough tablet in landscape, it functions as a normal, horizontal dropdown menu. But, on a mobile or portrait on a tablet, the menu is replaced with the usual 'hamburger' icon. That's what I've used, but what you use is up to you.

For the dropdown to work across all devices, there are several elements that need putting together. I have broken these up into the HTML elements, the JavaScript and finally, the CSS.

The HTML

Place each of the first two code snippets between the <head> and </head> tags on every page of your site. An excellent way to achieve this would be to copy it into the header.php file. The Navigation Menu part would be added wherever you would normally place your navigation.

Evoke jQuery

Without evoking jQuery, the whole of the dropdown menu will appear on the screen at once, whatever background colours you choose will be ignored, and clicking on the hamburger icon will do nothing.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>

The Responsive Meta Tag

This makes the browser render the width of the page as the width of its own screen. So if that screen is 320px wide, the browser window will be 320px wide, rather than using whatever psudo width the manufacturers of the device have programmed.

<meta name="viewport" content="initial-scale=1, width=device-width">

The Navigation Menu

This is just an example, so you should replace all the menu items with the titles of your own pages on your site

<div id="pattern" class="pattern">
<a href="#menu" class="menu-link"><img src="/images/menu.png" class="menu-icon" alt="menu button"></a>
<nav id="menu" class="menu" role="navigation">
<ul class="level-1">
<li><a href="/">Home</a></li>
<li class="has-subnav"><a>Top Level 1</a>
<ul class="level-2">
<li><a href="/sub-menu-item-1">Sub Menu Item 1</a></li>
<li><a href="/sub-menu-item-2">Sub Menu Item 2</a></li>
<li><a href="/sub-menu-item-3">Sub Menu Item 3</a></li>
<li class="bottom"><a href="/sub-menu-item-4">Sub Menu Item 4</a></li>
</ul>
</li>
<li><a href="/no-sub-menu-1">No Sub Menu 1</a></li>
<li class="has-subnav"><a>Top Level 2</a>
<ul class="level-2">
<li><a href="/sub-menu-item-5">Sub Menu Item 5</a></li>
<li><a href="/sub-menu-item-6">Sub Menu Item 6</a></li>
<li class="bottom"><a href="/sub-menu-item-7">Sub Menu Item 7</a></li>
</ul>
</li>
<li class="has-subnav"><a>Top Level 3</a>
<ul class="level-2">
<li><a href="/sub-menu-item-8">Sub Menu Item 8</a></li>
<li><a href="/sub-menu-item-9">Sub Menu Item 9</a></li>
<li><a href="/sub-menu-item-10">Sub Menu Item 10</a></li>
<li><a href="/sub-menu-item-11">Sub Menu Item 11</a></li>
<li class="bottom"><a href="/sub-menu-item-12">Sub Menu Item 12</a></li>
</ul>
</li>
<li class="has-subnav"><a>Top Level 4</a>
<ul class="level-2">
<li><a href="/sub-menu-item-13">Sub Menu Item 13</a></li>
<li><a href="/sub-menu-item-14">Sub Menu Item 14</a></li>
<li><a href="/sub-menu-item-15">Sub Menu Item 15</a></li>
<li><a href="/sub-menu-item-16">Sub Menu Item 16</a></li>
<li><a href="/sub-menu-item-17">Sub Menu Item 17</a></li>
<li class="bottom"><a href="/sub-menu-item-18">Sub Menu Item 18</a></li>
</ul>
</li>
<li class="has-subnav"><a>Top Level 5</a>
<ul class="level-2">
<li><a href="/sub-menu-item-19">Sub Menu Item 19</a></li>
<li class="bottom"><a href="/sub-menu-item-20">Sub Menu Item 20</a></li>
</ul>
</li>
<li><a href="/no-sub-menu-2">No Sub Menu 2</a></li>
</ul>
</nav>
</div>

The JavaScript

The JavaScript can be positioned between the <head> and </head> tags on every page of your site. Or, you could have it as a separate .js file.

<script type="text/javascript">
$(document).ready(function() {
    $('body').addClass('js');
  var $menu = $('#menu'),
    $menulink = $('.menu-link'),
    $menuTrigger = $('.has-subnav > a');

$menulink.click(function(e) {
e.preventDefault();
$menulink.toggleClass('active');
$menu.toggleClass('active');
});

$menuTrigger.click(function(e) {
e.preventDefault();
var $this = $(this);
$this.toggleClass('active').next('ul').toggleClass('active');
});

}); </script>

The CSS

Mobile First

#pattern {position: relative;
  z-index: 99999}

ul, li {list-style-type: none}

a.menu-link {float: right;
  display: block}

.menu, .menu > ul ul {clear: both;
  -webkit-transition: all 0.3s ease-out;
  -moz-transition: all 0.3s ease-out;
  -ms-transition: all 0.3s ease-out;
  -o-transition: all 0.3s ease-out;
  transition: all 0.3s ease-out}

.js .menu, .js .menu > ul ul {overflow: hidden;
  max-height: 0;
  background: #bfd8eb}

.menu.active, .js .menu > ul ul.active {max-height: 100em}

.menu > ul {border-top: 1px solid #acacac}

ul.level-2 li {background: #99c1df}

.menu li a {color: #000;
  display: block;
  padding: 0.8em;
  border-bottom: 1px solid #acacac;
  position: relative;
  text-decoration: none}

.menu li.has-subnav > a: after {content: '+';
  position: absolute;
  top: 0;
  right: 0;
  display: block;
  font-size: 1.5em;
  padding: 0.25em 0.5em}

.menu li.has-subnav > a.active: after {content: "-"}

.menu-icon {height: 60px;
  width: 62px;
  float: right}

Use a Media Query

@media screen and (min-width:1101px) {
DIFFERENT CSS GOES HERE
}

The Media Query and Styling the Menu for a Larger Screen

@media screen and (min-width:1101px){

.pattern {overflow: visible;
  top: 100px;
  height: 30px}

a.menu-link {display: none}

.js .menu, .js .menu > ul ul {max-height: none;
  overflow: visible;
  background: none}

.js .menu > ul ul {background: red;
  display: none}

.js .menu > ul li:hover > ul {display: block}

.menu ul {margin: 0;
  border: 0;
  font-size: 16px}

.menu li a {color: white;
  border: 0;
  padding: 0 22px;
  line-height: 30px}

.menu li.has-subnav > a {text-decoration: none;
  cursor: default}

.menu li.has-subnav > a: after, .menu .level-1 > li.has-subnav > a: after {display: none}

.menu > ul li {margin: 0}

.menu > ul > li {display: inline-block;
  position: relative}

.menu > ul ul {position: absolute;
  top: 0;
  left: 12em;
  width: 230px}

.menu > ul ul li {position: relative}

.menu > ul ul.level-2 {top: 30px;
  left: 0}

ul.level-2 li {background-color: white;
  font-weight: normal;
  border-bottom: 1px dotted #acacac;
  border-left: 1px solid #5f9dcc;
  border-right: 1px solid #ace2f0;
  font-size: 14px}

ul.level-2 li a {color: #5f9dcc;
  line-height: 40px}

ul.level-2 li a:hover {color: white;
  background-color: #ff9600}

ul.level-2 li.bottom {border-bottom: 2px solid #5f9dcc}

}

Mark founded PiciScan in 2010, and sold it in October 2015 to Web By Numbers Ltd, who now employ him! He likes Star Wars, playing escape games and looking after his bonsai tree.

comments powered by Disqus

The Latest From our Scanning Blog

Christmas 2015

Christmas 2015

Posted: 14 December 2015

It’s nearly the time of year to be going up into the loft and bringing down all the Christmas decorations, locating the tree and seeing if those lights from last year still work, or if you need to buy any more...

Read more

The Latest From our Web Design Blog

Box Sizing: Border-Box

Box Sizing: Border-Box

Posted: 24 March 2016

I first came across box-sizing: border-box when it cropped up in a temporary colleague's CSS. I found it pretty annoying when I picked up work that he'd started as it seemed to get in the way. This was because, as I said in a previous post on margin ...

Read more