With HTML 5 and CSS 3 now standard in most modern browsers, web developers can create interactive, attractive menus with ease. A few years ago we would be looking at using Javascript for many of the modern features, not now!
Here’s what we’ll be creating in this tutorial:
See the Pen LKsez
HTML
HTML 5 has many new elements/tags, the one we’re most interested in is <nav>
. The <nav>
element works in a similar way to <div>
but it’ll make it easier for screen readers and web bots to interoperate your page.
Using Lists
An important part of creating a site navigation is understanding that the navigation is a list
of links around your site.
What does that mean?
You need to use an unordered list to store your links, not a table!
HTML: the code
The HTML code is therefore very simple. We use <nav>
like a div and we use an unordered list (<ul>
). Let’s get started!
[html]
<nav>
<ul>
<li><a href="home.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="help.html">Help</a></li>
</ul>
</nav>
[/html]
This is a very simple navigation with a single tiered list. To create a dropdown menu we need to add a nested list inside one of the list-item elements.
[html]
<nav>
<ul>
<li><a href="home.html">Home</a></li>
<li>
<a href="products.html">Products <span class="caret"></span></a>
<div>
<ul>
<li><a href="products.html#chair">Chair</a></li>
<li><a href="products.html#table">Table</a></li>
<li><a href="cooker.html">Cooker</a></li>
</ul>
</div>
</li>
<li><a href="about.html">About</a></li>
<li><a href="help.html">Help</a></li>
</ul>
</nav>
[/html]
Inside the products 1st tier item we have 2 elements.
- Products link – You don’t need to use the “href” attribute but I always add a fallback
- Div – This contains our drop down menu or 2nd tier menu
If you wanted to create more levels to your menu then it’s very easy, keep embedding menus inside your list items. My recommendation is to use 3/4 levels at most as users will get lost very easily.
CSS
For my example I’ll be using the following body styling:
[css]body {
background-color: #EBE8E4;
color: #222;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
font-size: 15px;
}[/css]
First of all we need to style our nav element. You do this exactly the same way as styling a div in CSS.
[css]nav {
background-color: #fff;
border: 1px solid #dedede;
border-radius: 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
color: #888;
display: block;
margin: 8px 22px 8px 22px;
overflow: hidden;
width: 90%;
}[/css]
Let’s go through some of the CSS 3 and important styles in there –
Border-radius:
This gives us the rounded corners that used to be so hard to create. We’ve set a4px
radius across all corners.Box-shadow:
Add a nice shadow around our element. Syntax – box-shadow: h-shadow v-shadow blur spread color inset;RGBA:
RGB simply means Red, Green, Blue, it’s an alternative to using HEX colours. By having RGBA we’ve specified an “Alpha” or opacity value to our shadowMargin:
Done using the web developers compass (top, right, bottom, left), it specifies the “gap” around the elementOverflow:
This will stop any items breaking out of our element – used to fix a hover state on the list items
The next part of our HTML is the list, let’s create the CSS for that.
[css]nav ul {
margin: 0;
padding: 0;
}
nav ul li {
display: inline-block;
list-style-type: none;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
nav > ul > li > a {
color: #aaa;
display: block;
line-height: 56px;
padding: 0 24px;
text-decoration: none;
}[/css]
There are 2 important parts of the above code:
Inline-block:
By setting our list-items to inline block we can arrange them in a horizontal line without using floatCSS Transitions:
We’ve used a very basic transition here, “all” means all CSS attributes and “0.2s” refers to the amount of time they’ll take to transition
Creating a CSS triangle
CSS allows us to create different shapes by changing the size of different borders. This means that we can create a drop-down icon / down arrow by purely using CSS.
[css]nav > ul > li > a > .caret {
border-top: 4px solid #aaa;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
content: "";
display: inline-block;
height: 0;
width: 0;
vertical-align: middle;
-webkit-transition: color 0.1s linear;
-moz-transition: color 0.1s linear;
-o-transition: color 0.1s linear;
transition: color 0.1s linear;
}[/css]
As you can see, we’ve set the border-top to 4px and are using the left and right borders to shape the top border into the shape we want.
Creating CSS triangles is simple and easy to do. Have a play around and see what you can come up with. Here are some simple combinations:
Up Arrow:
Border-bottom: 5px solid, border-left: 5px transparent, border-right: 5px transparentDown Arrow:
Border-top: 5px solid, border-left: 5px transparent, border-right: 5px transparentLeft Arrow:
Border-left: 5px solid, border-top: 5px transparent, border-bottom: 5px transparentRight Arrow:
Border-right: 5px solid, border-top: 5px transparent, border-bottom: 5px transparent
Hover States
An important rule when creating user interface designs is to make sure things change when they expect them to, i.e. Hover states on links are very important. Below are our basic hover states for the list items in our 1st tier navigation.
[css]
nav > ul > li:hover {
background-color: rgb( 40, 44, 47 );
}
nav > ul > li:hover > a {
color: rgb( 255, 255, 255 );
}
nav > ul > li:hover > a > .caret {
border-top-color: rgb( 255, 255, 255 );
}[/css]
CSS 3 Drop-down Menu
Finally we need to style the containing div that holds our 2nd menu. There are 2 important parts to this styling:
Position Absolute:
This will place the menu outside of the nav bar and will allow you to display it on-top of other contentDisplay None:
You need to display none by default so the menu is hidden until someone hovers over the parent link
[css]nav > ul > li > div {
background-color: rgb( 40, 44, 47 );
border-top: 0;
border-radius: 0 0 4px 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
display: none;
margin: 0;
opacity: 0;
position: absolute;
width: 165px;
visibility: hidden;
z-index: 100;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
nav > ul > li > div ul > li {
display: block;
}
nav > ul > li > div ul > li > a {
color: #fff;
display: block;
padding: 12px 24px;
text-decoration: none;
}
nav > ul > li > div ul > li:hover > a {
background-color: rgba( 255, 255, 255, 0.1);
}[/css]
The question I get asked most about this code is – How do I make the drop-down menu appear? This is how –
[css]nav > ul > li:hover > div {
display: block;
opacity: 1;
visibility: visible;
}[/css]
The above code is saying when you hover over the parent list item then give the div element inside it the following style.
The Code – Two Tier Dropdown
Note: I’ve created an update to this tutorial below with a third tier, if you wish to use 3 levels then please see the update below for the full code.
HTML
[html]
<nav>
<ul>
<li><a href="home.html">Home</a></li>
<li>
<a href="products.html">Products <span class="caret"></span></a>
<div>
<ul>
<li><a href="products.html#chair">Chair</a></li>
<li><a href="products.html#table">Table</a></li>
<li><a href="cooker.html">Cooker</a></li>
</ul>
</div>
</li>
<li><a href="about.html">About</a></li>
<li><a href="help.html">Help</a></li>
</ul>
</nav>
[/html]
CSS
[css]body {
background-color: #EBE8E4;
color: #222;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
font-size: 15px;
}
nav {
background-color: #fff;
border: 1px solid #dedede;
border-radius: 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
color: #888;
display: block;
margin: 8px 22px 8px 22px;
overflow: hidden;
width: 90%;
}
nav ul {
margin: 0;
padding: 0;
}
nav ul li {
display: inline-block;
list-style-type: none;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
nav > ul > li > a > .caret {
border-top: 4px solid #aaa;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
content: "";
display: inline-block;
height: 0;
width: 0;
vertical-align: middle;
-webkit-transition: color 0.1s linear;
-moz-transition: color 0.1s linear;
-o-transition: color 0.1s linear;
transition: color 0.1s linear;
}
nav > ul > li > a {
color: #aaa;
display: block;
line-height: 56px;
padding: 0 24px;
text-decoration: none;
}
nav > ul > li:hover {
background-color: rgb( 40, 44, 47 );
}
nav > ul > li:hover > a {
color: rgb( 255, 255, 255 );
}
nav > ul > li:hover > a > .caret {
border-top-color: rgb( 255, 255, 255 );
}
nav > ul > li > div {
background-color: rgb( 40, 44, 47 );
border-top: 0;
border-radius: 0 0 4px 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
display: none;
margin: 0;
opacity: 0;
position: absolute;
width: 165px;
visibility: hidden;
z-index: 100;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
nav > ul > li:hover > div {
display: block;
opacity: 1;
visibility: visible;
}
nav > ul > li > div ul > li {
display: block;
}
nav > ul > li > div ul > li > a {
color: #fff;
display: block;
padding: 12px 24px;
text-decoration: none;
}
nav > ul > li > div ul > li:hover > a {
background-color: rgba( 255, 255, 255, 0.1);
}[/css]
If you want to find out how to create a three tier dropdown menu then please continue reading.
Creating the Third Level Dropdown Menu
I’ve been asked by numerous people how to extend this tutorial to create a third level dropdown menu. Fortunately this is relatively easy and uses much of the same code as before.
Here’s what the updated will do –
See the Pen lHoce by lawnch (@lawnch) on CodePen.
Creating the New Caret
As the current caret indicates a dropdown, we need to create a caret to indicate a sideways movement. This is done like so:
[css]nav > ul > li > a > .caret,
nav > ul > li > div ul > li > a > .caret {
border-top: 4px solid #aaa;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
content: "";
display: inline-block;
height: 0;
width: 0;
vertical-align: middle;
-webkit-transition: color 0.1s linear;
-moz-transition: color 0.1s linear;
-o-transition: color 0.1s linear;
transition: color 0.1s linear;
}
nav > ul > li > div ul > li > a > .caret {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
border-right: 4px solid transparent;
border-left: 4px solid #f2f2f2;
margin: 0 0 0 8px;
}[/css]
Importantly, we set the new caret to have identical styles to the downward one. Next we modify the direction it points through the use of transparent borders. To understand the different directions you can make the arrow point, I’ve discussed it earlier on.
3rd Layer Container
Similarly to the caret, we need to copy a previous style for the container and then modify it for the 3rd level.
[css]nav > ul > li > div,
nav > ul > li > div ul > li > div {
background-color: rgb( 40, 44, 47 );
border-top: 0;
border-radius: 0 0 4px 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
display: none;
margin: 0;
opacity: 0;
position: absolute;
width: 165px;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
nav > ul > li > div ul > li > div {
border-radius: 0 4px 4px 4px;
box-shadow: inset 2px 0 5px rgba(0,0,0,.15);
margin-top: -42px;
right: -165px;
}
nav > ul > li:hover > div,
nav > ul > li > div ul > li:hover > div {
display: block;
opacity: 1;
visibility: visible;
}[/css]
Let’s deconstruct the second style definition in there:
border-radius: 0 4px 4px 4px;
– this sets a 4px radius to all corners except the top left, which gives the box a good flow.box-shadow
– the shadow is set to run down the left side of the box, on the inside, making the box look below the second tiermargin-top
– this pulls the box up so it’s flush level with the container elementright
– pulls the container right by 165px (the width of the second tier box)
The code – Three Tier CSS Navigation Menu
These are the two main changes from a two tier menu to a three tier. Below is the full code to use on your website:
HTML
Download here –
[html]
<nav>
<ul>
<li><a href="home.html">Home</a></li>
<li>
<a href="products.html">Products <span class="caret"></span></a>
<div>
<ul>
<li>
<a href="products.html#chair">Chair <span class="caret"></span></a>
<div>
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
</ul>
</div>
</li>
<li><a href="products.html#table">Table</a></li>
<li><a href="cooker.html">Cooker</a></li>
</ul>
</div>
</li>
<li><a href="about.html">About</a></li>
<li><a href="help.html">Help</a></li>
</ul>
</nav>
[/html]
CSS
Download here –
[css]body {
background-color: #EBE8E4;
color: #222;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
font-size: 15px;
}
nav {
background-color: #fff;
border: 1px solid #dedede;
border-radius: 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
color: #888;
display: block;
margin: 8px 22px 8px 22px;
overflow: hidden;
width: 90%;
}
nav ul {
margin: 0;
padding: 0;
}
nav ul li {
display: inline-block;
list-style-type: none;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
nav > ul > li > a > .caret,
nav > ul > li > div ul > li > a > .caret {
border-top: 4px solid #aaa;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
content: "";
display: inline-block;
height: 0;
width: 0;
vertical-align: middle;
-webkit-transition: color 0.1s linear;
-moz-transition: color 0.1s linear;
-o-transition: color 0.1s linear;
transition: color 0.1s linear;
}
nav > ul > li > div ul > li > a > .caret {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
border-right: 4px solid transparent;
border-left: 4px solid #f2f2f2;
margin: 0 0 0 8px;
}
nav > ul > li > a {
color: #aaa;
display: block;
line-height: 56px;
padding: 0 24px;
text-decoration: none;
}
nav > ul > li:hover {
background-color: rgb( 40, 44, 47 );
}
nav > ul > li:hover > a {
color: rgb( 255, 255, 255 );
}
nav > ul > li:hover > a > .caret {
border-top-color: rgb( 255, 255, 255 );
}
nav > ul > li > div ul > li:hover > a > .caret {
border-left-color: rgb(255,255,255);
}
nav > ul > li > div,
nav > ul > li > div ul > li > div {
background-color: rgb( 40, 44, 47 );
border-top: 0;
border-radius: 0 0 4px 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);
display: none;
margin: 0;
opacity: 0;
position: absolute;
width: 165px;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
nav > ul > li > div ul > li > div {
background-color: rgb( 40, 44, 47 );
border-radius: 0 4px 4px 4px;
box-shadow: inset 2px 0 5px rgba(0,0,0,.15);
margin-top: -42px;
right: -165px;
}
nav > ul > li:hover > div,
nav > ul > li > div ul > li:hover > div {
display: block;
opacity: 1;
visibility: visible;
}
nav > ul > li > div ul > li,
nav > ul > li > div ul > li > div ul > li {
display: block;
position: relative;
}
nav > ul > li > div ul > li > a,
nav > ul > li > div ul > li > div ul > li > a {
color: #fff;
display: block;
padding: 12px 24px;
text-decoration: none;
}
nav > ul > li > div ul > li:hover > a {
background-color: rgba( 255, 255, 255, 0.1);
}[/css]
Conclusion
Thanks for reading this tutorial, let me know what you come up with in the comments below.
If there are any web development subjects you want me to cover then feel free to contact me!
Subscribe for Updates
Get notified about my latest content first and receive invitations for subscriber only competitions.
Wow! I do not think so. And not simply nice submit”.
adam plzz start this type of course on angularjs…. thank you
I’ll take a look but I haven’t explored AngularJS much myself
Great tutorial! Easy to get
Great. Very helpful.
Thanks for this epic post! Keep up the great work Adam!
Great tutorial.
The use of CSS for Navigation A great tutorial you have captured how a navigation bar is a list of links, the and reused. I teach year 11 and 12 they find with a little support from me easy to follow
Adam – is the div enclosing the submenu actually necessary?
Would it work as well to use
Nav > ul > li > ul and
<li
instead of approach you describe? If not, why not?
Thanks, really helpful with navbar 😉