With CSS 3 and HTML5 browser support now much more prominent and widely used, we can start to implement more of their features into our own website. This tutorial will look at combining some CSS 3 and HTML5 features to create a nice, simple navigation bar for your website. We'll look at how to add browser specific fallbacks into the code to prevent older browsers from showing something different.

With HTML5 being supported now in Internet Explorer, this tutorial assumes the browser you're using will support HTML5. If you're finding this to be an issue then there's a great Javascript fallback to create the new HTML5 elements in older browsers.

Check out this Pen!

Creating the HTML

It's important when creating any navigation to treat your links as a list. Because of this we're going to be using the unordered list element - "ul" to hold our navigation. To begin with we need to create our navigation bar / block element. For this we're going to use the new "nav" element.

<nav>
<!--Code goes here-->
</nav>

Within this navigation we want to hold our unordered list:

<nav>
	<ul>
		<!--Code goes here-->
	</ul>
</nav>

Finally we want to create our base navigation elements, our list items.

<nav>
	<ul>
		<li><a href="home.html">Home</a></li>
		<li><a href="products.html">Products</a></li>
		<li><a href="about.html">About</a></li>
		<li><a href="help.html">Help</a></li>
	</ul>
</nav>

With our basic navigation list complete we can now add our dropdown menu HTML. To do this we're going to use a nested unordered list within one of the list items. This is done like so:

<nav>
	<ul>
		<li><a href="home.html">Home</a></li>
		<li>
			<a href="products.html">Products</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>

With our HTML complete we can begin creating our CSS to style this element.

Styling with CSS

Before we begin styling the navigation bar I'm going to create a nice background colour and choose a nice font to use on our website. The code listed below is optional but will make the example look better if you choose to view it on your local machine.

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;
}

Firstly it's important to style the parent element, the navigation bar. We want to make the bar stand out as well as span the width of the page. To do this we're going to use display: block and set a white background colour.

nav {
  background-color: #fff;
  border: 1px solid #dedede;
  color: #888;
  display: block;
  margin: 8px 22px 8px 22px;
  width: 90%; 
}

Now with CSS 3 being supported by most browsers we can create nicer, more attractive designs. Two styles that help with this are CSS 3 border-radius and box-shadow. For both of these you may wish to add fallbacks in certain browsers. To add a fallback you simply need to do -moz-/-webkit-/-o- + the style you want. For example,

-moz-border-radius: 4px; /* Firefox */
-webkit-border-radius: 4px; /* Safari and Chrome */
-o-border-radius: 4px; /* Opera */
border-radius: 4px; /* Normal CSS 3 */

With that said, we now want to add a border radius and box shadow to our element, to do that we simply do:

border-radius: 4px;
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.055);

Our complete nav style should now look like this:

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;
  width: 90%; 
}

Styling the basic list itself is pretty straight forward. First of all we want to make sure there's no margin or padding being added to the list via the browser. If you're using a reset CSS file then you won't need to worry about doing that. Secondly you want to remove the bullet points from the list by using "list-style-type: none". The most important style to add to the list items is making them display "inline-block", that means all the items will be shown horizontally rather than in a vertical list. The code for all of this looks like so:

  nav ul {
    margin: 0;
    padding: 0;
  }

    nav ul li {
      display: inline-block;
      list-style-type: none;
    }

To make the list items stand out we need to add padding and remove default link styling to add some design flare. We're also going to include a simple CSS3 transition / animation for the hover state so the colour changes with a fade.

nav > ul > li > a {
	color: #aaa;
	display: block;
	line-height: 56px;
	padding: 0 16px;
	text-decoration: none;

	-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:hover > a {
	  color: rgb( 248, 66, 66 );
	}

By default we need to make sure the dropdown element isn't shown until the user hovers over the parent element. When we style the inner "dropdown" box we need to set the default style to "display: none". In this example I'm going to make the dropdown element look similar to the navigation bar, you can style it however you like.

When hovering over the parent list item we need to make sure the dropdown div then displays by using :hover and display: block:

nav > ul > li > div {
	background-color: #fff;
	border: 1px solid #dedede;
	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;
	position: absolute;
	width: 165px;
}

	nav > ul > li:hover > div {
		display: block;
	}

Finally we want to add styling to the dropdown list. This is very simple and is similar to how we styled the parent list:

nav > ul > li > div ul > li {
	display: block;
}

	nav > ul > li > div ul > li > a {
		border-bottom: 1px solid #f2f2f2;
		color: #ccc;
		display: block;
		padding: 4px 6px;
		text-decoration: none;
	}

		nav > ul > li > div ul > li:hover > a {
			background-color: #f2f2f2;
			color: rgb( 248, 66, 66 );
		}

Adding a dropdown arrow

There are some nice tricks within CSS for creating shapes without using images. A down arrow in a dropdown menu is a good example of where this can be used. To do this we use some simple border tricks by setting the top border to a certain width and making the side borders convert it into an arrow. You should set the border colour similar to the text colour for good parity between elements

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:hover > a > .caret {
		border-top-color: rgb( 248, 66, 66 );
	}

To add this into the HTML you simply use a span element with a class of caret:

<a href="products.html">Products <span class="caret"></span></a>

Final code

Thanks for reading this tutorial, all my code has been posted below. Post your results in the forum or in the comments below.

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>

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;
  width: 90%; 
}

  nav ul {
    margin: 0;
    padding: 0;
  }

    nav ul li {
      display: inline-block;
      list-style-type: none;
    }

      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 16px;
        text-decoration: none;

        -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:hover > a {
          color: rgb( 248, 66, 66 );
        }

        nav > ul > li:hover > a > .caret {
          border-top-color: rgb( 248, 66, 66 );
        }

      nav > ul > li > div {
        background-color: #fff;
        border: 1px solid #dedede;
        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;
        position: absolute;
        width: 165px;
      }

        nav > ul > li:hover > div {
          display: block;
        }

          nav > ul > li > div ul > li {
            display: block;
          }

            nav > ul > li > div ul > li > a {
              border-bottom: 1px solid #f2f2f2;
              color: #ccc;
              display: block;
              padding: 4px 6px;
              text-decoration: none;
            }

              nav > ul > li > div ul > li:hover > a {
                background-color: #f2f2f2;
                color: rgb( 248, 66, 66 );
              }