responsive-menu-thumb

Creating a Responsive Menu with HTML, CSS & jQuery

Today I’m going to show you how to create a responsive menu with HTML, CSS and jQuery. I’m going to go over how to style the menu, using media queries and how to make the hamburger button toggle the menu.

Table of Contents

  1. Skip to the HTML
  2. Skip to the CSS
  3. Skip to the jQuery

You might also like: Creating a Dropdown Menu with HTML & CSS


1 Structuring The HTML

Complete HTML

<nav class="menu">
    <ul class="active">
        <li class="current-item"><a href="#">Home</a></li>
        <li><a href="#">My Work</a></li>
        <li><a href="#">About Me</a></li>
        <li><a href="#">Get in Touch</a></li>
        <li><a href="#">Blog</a></li>
    </ul>

    <a class="toggle-nav" href="#">&#9776;</a>

    <form class="search-form">
        <input type="text">
        <button>Search</button>
    </form>
</nav>

HTML Explained

The nav element is the housing of the entire menu and the class of menu will be the starting point for all CSS selectors.

<nav class="menu">

</nav>

An unordered list, holding all the menu links, has a class of active which is used to toggle it from visible to hidden.

<ul class="active">
    
</ul>

The list item that is currently active, for example the page you’re on, is highlighted through CSS by using the selector current-item.

<li class="current-item"><a href="#">Home</a></li>

A class of toggle-nav has been added to the anchor link between the ul and form so it can be hidden or visible depending on the window size, I cover this below using media queries. It also uses the Unicode symbol of three lines, e.g. .

<a class="toggle-nav" href="#">&#9776;</a>

A basic form with an input and button is used as an example so the content styles can change depending on the window size.

<form class="search-form">
    <input type="text">
    <button>Search</button>
</form>

2 Styling with CSS

Complete CSS

/*----- Toggle Button -----*/
.toggle-nav {
    display:none;
}

/*----- Menu -----*/
@media screen and (min-width: 860px) {
    .menu {
        width:100%;
        padding:10px 18px;
        box-shadow:0px 1px 1px rgba(0,0,0,0.15);
        border-radius:3px;
        background:#303030;
    }
}

.menu ul {
    display:inline-block;
}

.menu li {
    margin:0px 50px 0px 0px;
    float:left;
    list-style:none;
    font-size:17px;
}

.menu li:last-child {
    margin-right:0px;
}

.menu a {
    text-shadow:0px 1px 0px rgba(0,0,0,0.5);
    color:#777;
    transition:color linear 0.15s;
}

.menu a:hover, .menu .current-item a {
    text-decoration:none;
    color:#66a992;
}

/*----- Search -----*/
.search-form {
    float:right;
    display:inline-block;
}

.search-form input {
    width:200px;
    height:30px;
    padding:0px 8px;
    float:left;
    border-radius:2px 0px 0px 2px;
    font-size:13px;
}

.search-form button {
    height:30px;
    padding:0px 7px;
    float:right;
    border-radius:0px 2px 2px 0px;
    background:#66a992;
    font-size:13px;
    font-weight:600;
    text-shadow:0px 1px 0px rgba(0,0,0,0.3);
    color:#fff;
}

/*----- Responsive -----*/
@media screen and (max-width: 1150px) {
    .wrap {
        width:90%;
    }
}

@media screen and (max-width: 970px) {
    .search-form input {
        width:120px;
    }
}

@media screen and (max-width: 860px) {
    .menu {
        position:relative;
        display:inline-block;
    }

    .menu ul.active {
        display:none;
    }

    .menu ul {
        width:100%;
        position:absolute;
        top:120%;
        left:0px;
        padding:10px 18px;
        box-shadow:0px 1px 1px rgba(0,0,0,0.15);
        border-radius:3px;
        background:#303030;
    }

    .menu ul:after {
        width:0px;
        height:0px;
        position:absolute;
        top:0%;
        left:22px;
        content:'';
        transform:translate(0%, -100%);
        border-left:7px solid transparent;
        border-right:7px solid transparent;
        border-bottom:7px solid #303030;
    }

    .menu li {
        margin:5px 0px 5px 0px;
        float:none;
        display:block;
    }

    .menu a {
        display:block;
    }

    .toggle-nav {
        padding:20px;
        float:left;
        display:inline-block;
        box-shadow:0px 1px 1px rgba(0,0,0,0.15);
        border-radius:3px;
        background:#303030;
        text-shadow:0px 1px 0px rgba(0,0,0,0.5);
        color:#777;
        font-size:20px;
        transition:color linear 0.15s;
    }

    .toggle-nav:hover, .toggle-nav.active {
        text-decoration:none;
        color:#66a992;
    }

    .search-form {
        margin:12px 0px 0px 20px;
        float:left;
    }

    .search-form input {
        box-shadow:-1px 1px 2px rgba(0,0,0,0.1);
    }
}

Standard CSS Explained

Don’t get put off if it looks like a lot of CSS. Here’s a run down of what’s going on:

Firstly the .toggle-nav button is hidden.

.toggle-nav {
    display:none;
}

The menu has styling applied but by using a media query of min-width we can specify that the styling will only apply untill the window is equal to or more than 860px.

@media screen and (min-width: 860px) {
    .menu {
        width:100%;
        padding:10px 18px;
        box-shadow:0px 1px 1px rgba(0,0,0,0.15);
        border-radius:3px;
        background:#303030;
    }
}

rgba(0,0,0,0.5) is used on a few items in the CSS. RGBA stands for Red, Green, Blue and Alpha. Alpha means the transparency/opacity. For example, an alpha of 0.6 would be 60% opacity but an alpha of 0.06 would be 6% opacity.

text-shadow:0px 1px 0px rgba(0,0,0,0.5);

The :last-child selector is used to specify that the last list item will have no margin applied to it, otherwise as the window gets smaller the search form would go onto the next line before it’s supposed to.

.menu li:last-child {
    margin-right:0px;
}

The transitions in the menu, for example the fading of colors from grey to green, use the standard transition. However if you’re supporting older versions of browsers you may want to use prefixed code. The code is mostly the same however you prefix the transition like so:

Webkit: -webkit-transition:;
– Firefox: -moz-transition:;
– IE: -ms-transition:;
– Opera: -o-transition:; – Please note that Opera now runs on Webkit so this one is outdated but still good to know.

transition:color linear 0.15s;

Responsive CSS Explained

A little like before with .menu when min-width was used we’ll now be using max-width which does the opposite. The styles with in a max-width media query will only take effect once the window gets to a certain size. This is the most common type of media query.

The first breakpoint is set at 970px and shortens the input in the .search-form. This is a useful technique when you don’t want to start hiding the menu but need to make some changes so the styles don’t break.

@media screen and (max-width: 970px) {
    .search-form input {
        width:120px;
    }
}

The second breakpoint is set at 860px and houses the majority of the responsive styling. The .menu is given a position of relative so the ul can be positioned absolutely inside of it.

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

To hide the menu and help the jQuery the .menu ul.active class is hidden. This comes into play when you toggle the .active class with jQuery.

.menu ul.active {
    display:none;
}

Adding the arrow to the top of the ul is achieved using the :after pseudo element. Don’t forget to always add content:''; to any pseudo element or else it won’t show up.

Positioning of the arrow is achieved using absolute positioning and CSS transforms, more specifically translate. The values of 0% and -100% state 0% from the left and -100% from the top.

.menu ul:after {
    width:0px;
    height:0px;
    position:absolute;
    top:0%;
    left:22px;
    content:'';
    transform:translate(0%, -100%);
    border-left:7px solid transparent;
    border-right:7px solid transparent;
    border-bottom:7px solid #303030;
}

The toggle button and search form then just use some basic CSS styling to change things around a little.


3 Toggling with jQuery

Complete jQuery

jQuery(document).ready(function() {
    jQuery('.toggle-nav').click(function(e) {
        jQuery(this).toggleClass('active');
        jQuery('.menu ul').toggleClass('active');

        e.preventDefault();
    });
});

jQuery Explained

The jQuery starts off with a click call on the .toggle-nav button. The e stands for event.. You could use any name you like but it’s standard to use either e or event.

jQuery('.toggle-nav').click(function(e) {
    
});

Then you toggle the active class on that .toggle-nav button and the ul in the menu. You could combine this into one line but for the sake of this tutorial it’s best to keep them separate so you can clearly see what’s happening.

jQuery(this).toggleClass('active');
jQuery('.menu ul').toggleClass('active');

Finally you tell jQuery to prevent the default behavior of the .toggle-nav button. Since it’s actually an anchor link it’ll put a # the address bar and jump the page to the top if we don’t remove its default behavior.

e.preventDefault();

Conclusion and Further Reading

Going responsive is hard. It takes a lot of research and practice to get right. I hope this tutorial has helped your understanding of how to implement a responsive navigation menu into your projects.

If you have any questions or comments just leave them below and I’ll get back to you ASAP.

Here are a few resources that should help:

You might also like: Create a Fading Popup Modal with jQuery

Follow IP on Twitter Like IP on Facebook

Advertisement