Web Development optimize

Effective website navigation using CSS3

Ryan Boudreaux presents a tutorial on revamping your website's navigation using only CSS3 -- no JavaScript or images.

Maybe it's time to revamp your website navigation, or maybe you just want to create a new look and feel. Is your navigation and interface system user friendly? Or do your visitors get bogged down steering through your website? This tutorial will help you create a new navigation with drop-down menus on your website using pure CSS3 technology to build a user friendly interface and improved user experience -- all this too without using any JavaScript and minimal use of images.

The power of CSS3 makes it possible for us to create some robust navigation and drop-down menus that are useful across most browsers. The step by step process will include building the navigation bar in HTML, and then adding containers with some CSS3 styling, then styling the menu items, and coding the drop-down menus and their associated styling. Then we will look at several column variations on the theme to round out the lesson.

The navigation bar

First we will build out our demonstration navigation menu bar using an unordered list defined in the HTML which will be inside the HTML5 <nav> container and we will give the unordered list an id="nav_menu":

      <nav>
        <ul id="nav_menu">
            <li><a href="#">Home</a></li>
            <li><a href="#">About</a></li>
            <li><a href="#">Blog</a></li>
            <li><a href="#">Products</a></li>
            <li><a href="#">Services</a></li>
            <li><a href="#">Contact</a></li>
        </ul>
      </nav>

The example in its unstyled form looks like this as displayed in Chrome 16.0.912.63 m:

Figure A

And now for our first CSS3 styling, we will define a list-style which is set to none; a fixed width of 800px, which gets centered through setting the left and right margins to "auto"; a height of 60px; and the left and right padding set to 40px each.

#nav_menu {
      list-style:none;
      width:800px;
      margin:40px auto 0px auto;
      height:60px;
      padding:0px 40px 0px 40px;

Now let's add a background color and a gradient to the stylesheet using moz, webkit, o, and ms prefixes, along with a filter for IE6-9. The first background indicated is the fallback color for older browsers, and then we define the gradients with a top down vertical color using the two colors, #b0b1d8 and #0e0f09.

background: #b0b1d8;
background: -moz-linear-gradient(top,  #b0b1d8 0%, #0e0f09 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b0b1d8), color-stop(100%,#0e0f09));
background: -webkit-linear-gradient(top,  #b0b1d8 0%,#0e0f09 100%);
background: -o-linear-gradient(top,  #b0b1d8 0%,#0e0f09 100%);
background: -ms-linear-gradient(top,  #b0b1d8 0%,#0e0f09 100%);
background: linear-gradient(top,  #b0b1d8 0%,#0e0f09 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b0b1d8', endColorstr='#0e0f09',GradientType=0 );

Next, we will add in a 1px border and 1px box-shadow to simulate a border effect using inset by defining a horizontal and vertical offset with a blur radius of 1px.

border: 1px solid #3f4c6b;
-moz-box-shadow:inset 0px 0px 1px #3f4c6b;
-webkit-box-shadow:inset 0px 0px 1px #3f4c6b;
-o-box-shadow:inset 0px 0px 1px #3f4c6b;
-ms-box-shadow:inset 0px 0px 1px #3f4c6b;
box-shadow:inset 0px 0px 1px #3f4c6b;

This is how our menu navigation looks now as displayed in Chrome 16.0.912.63 m:

Figure B

(Click to enlarge all images.)

Before we address the menu list styling and how it needs to be on the horizontal, we will now add in a border-radius of 12px to smooth out the edges of the background.

-moz-border-radius: 12px
-webkit-border-radius: 12px;
-o-border-radius: 12px;
-ms-border-radius: 12px;
border-radius: 12px;

And the border-radius brings our navigation menu bar looking a bit smoother as displayed in Chrome 16.0.912.63 m:

Figure C

Menu list items styling

Next we will add styling to the menu list items so that they are evenly spaced across the navigation menu bar using alignment, margins, and padding, and starting with the menu list items.

#nav_menu li {
      float:left;
      display:block;
      text-align:center;
      position:relative;
      padding: 8px 20px 8px 20px;
      margin-right:30px;
      margin-top:10px;
      border:none;
}
Our navigation menu bar is starting to take better shape now as displayed in both Dreamweaver's preview pane at the top and in Chrome 16.0.912.63 m on the bottom in Figure D:

Figure D

Next we will establish a hover state for the menu items and drop down lists adding a light slate color scheme using HEX #778899 as the base and a gradient to HEX #EDF1F5. Starting with a 1px solid border color HEX #566370, padding with 19px for the left side to compensate for the 1px border, and then adding the linear-gradient (with prefixes for moz, webkit, o, and ms) with a border-radius of 7px for the top left and top right sides only, we create the rounded corners for a tabbed effect surrounding each list on hover.

#nav_menu li:hover {
      border: 1px solid #566370;
      padding: 8px 20px 8px 19px;
      /* Background color and gradients */
      background: #778899;
      background: -moz-linear-gradient(top, #778899, #EDF1F5);
      background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#778899), to(#EDF1F5));
      background: -webkit-linear-gradient(top, #778899, #EDF1F5);
      background: -o-linear-gradient(top, #778899, #EDF1F5);
      background: -ms-linear-gradient(top, #778899, #EDF1F5);
      background: linear-gradient(top, #778899, #EDF1F5);
      /* Rounded corners */
      -moz-border-radius: 7px 7px 0px 0px;
      -webkit-border-radius: 7px 7px 0px 0px;
      -o-border-radius: 7px 7px 0px 0px;
      -ms-border-radius: 7px 7px 0px 0px;
      border-radius: 7px 7px 0px 0px;
}

The result with the background and radius styling added is displayed below in Chrome 16.0.912.63 m:

Figure E

Next we will style the menu list item anchors:

  • font family of Trebuchet MS, Helvetica, sans-serif with small caps font variant
  • font size of 16px and font weight of 300
  • HEX #EDF1F5 color
  • set the display to block
  • text decoration to none
  • text shadow.
#nav_menu li a {
      font-family:'Trebuchet MS', Helvetica, sans-serif;
      font-variant: small-caps;
      font-size:16px;
      font-weight:600;
      color: #EDF1F5;
      display:block;
      outline:0;
      text-decoration:none;
      text-shadow: 2px 1px 1px #000;
}

The result with the menu list anchor styling added is displayed below in Chrome 16.0.912.63 m:

Figure F

Next, we will add a menu list anchor hover effect which will make the color darker and change the shadow color to HEX #99ACC2, which is a slight variant on the light slate color.

#nav_menu li:hover a {
      color:#323438;
      text-shadow: 2px 1px 1px #99ACC2;
}

The result with the menu list hover styling added is displayed below in Chrome 16.0.912.63 m:

Figure G

Next, we will add a drop-down arrow image for the menu list and for the list on hover, adding in a slight shadow effect on mouse hover; the right padding of 20px ensures that the image is placed to the right side of the menu item text.

#nav_menu li .drop_down {
      padding-right:20px;
      background:url("images/arrow_btn_down.gif") no-repeat right 8px;
}
#nav_menu li:hover .drop_down {
      background:url("images/arrow_btn_down_hover.gif") no-repeat right 7px;
}

The result with the drop-down arrow imaged added to the menu list and hover styling is displayed below in Chrome 16.0.912.63 m:

Figure H

To solve for the IE6 and lower browser hover issue, we add in the if IE script, which also points to the csshover3.htc file:

<!--[if IE 6]>
  <style>
    body {behavior: url("csshover3.htc");}
    #nav_menu li .drop_down {background:url("images/arrow_btn_down_hover.gif") no-repeat right 7px;
  </style>
<![endif]-->

In the next segment of this tutorial, we well add in the drop down menu content and styling creating the general structure using containers, along with the option for either one or multiple columns of content, and styling.

About

Ryan has performed in a broad range of technology support roles for electric-generation utilities, including nuclear power plants, and for the telecommunications industry. He has worked in web development for the restaurant industry and the Federal g...

13 comments
kimsymmons
kimsymmons

All well and good but I notice that there CSS for techrepublic has some very odd rules conflicts so that the links within the masthead navigation flash an underline before being over written with the masthead styles. Looks like the on hover drop down menu is used to cover the a:link hover mouse over... a:focus, a:hover { -moz-text-blink: none; -moz-text-decoration-color: -moz-use-text-color; -moz-text-decoration-line: underline; -moz-text-decoration-style: solid; } OSX using FF 8.0.1

adamo.g79
adamo.g79

Hi there. Great stuff. The only thing i have a problem is this line of code.It's not working for me. #nav_menu li .drop_down { padding-right:20px; background:url("images/arrow_btn_down.gif") no-repeat right 8px; } (I've got my own images) I'm assuming you've added a class="drop_down" to the tags. Is this correct? Thanks for a reply.

SpatsTriptiphan
SpatsTriptiphan

Any chance of getting the file instead of copying it from the page? Many Thanks

gak
gak

So, if in CSS3 I have to do the same thing over and over with -o, -moz, -ms, -web, I would better stay with JavaScript where all that shit is handled by jQuery. However, CSS3, is definitely the future, WHEN FINALLY DONE.

IanDSamson
IanDSamson

I fail to see how a href=# can navigate anywhere! Does the author mean to fill in the full URL to Home, About, Blog, Products, etc in place of the # at a later stage? I do not see the URL anywhere else in the code.

randy
randy

Why not set something up that will work nicely with smartphone-sized browser windows too?

itadmin
itadmin

The complexity for this sort of thing which was in the javascript is now in the css. A lot of new css to learn. It most likely is an improvement, but not as big an improvement as some make it out to be.

RJBoudreaux
RJBoudreaux

I meant to show the updated HTML, the class="drop_down" is added to each of the anchor tags.

RJBoudreaux
RJBoudreaux

Will be available in part 2 which will be posted later in the week.

RJBoudreaux
RJBoudreaux

The "href="#" are placeholders for tutorial example purposes only, and to eliminate having to add an additional five HTML files. You can always add in the anchor references to the files and create your own additional pages, i.e. home.html, about.html, etc...

RJBoudreaux
RJBoudreaux

Of course, you can modify the fixed width:800px; for the #nav_menu and change it to a percentage such as width:80%; for example.

macminn@internode.on.net
macminn@internode.on.net

Hi There, A very good article. Any signs of part 2??? I'm looking forward to getting my good looking menu to do something more than look good.

Thorium
Thorium

Hi, I enjoy your articles. Thank you for sharing. Awaiting part 2 [(:-).