CSS Navigation Example

I've decided to try putting together a concept I had for navigation. The idea was to have navigation buttons that appeared to come out from underneath another element. I wanted to try and combine a number of the CSS tips and tricks that are available into one well-implemented example.

The navigation on the site as of this writing uses the Sliding Doors technique. It works well and definitely adds something to the look of the site. But I want funk! So, time to funkify!

Using the Pixy 'No preload' rollovers technique, I've put together the first example.

The HTML is pretty straighforward. My opinion is that CSS should be practical and shouldn't require additional span and div tags to achieve the design you require.

<div id="bg">
   <div id="header">
     here is some text
   </div>
   <div id="img">
     <ul>
       <li><a href="#">Home</a></li>
       <li><a href="#">Resume</a></li>
       <li><a href="#">Coding</a></li>
       <li><a href="#">Contact</a></li>
     </ul>
     </div>
   <div class="clear">&nbsp;</div>
</div>

The header 'bg' div is simply for applying the background in the example. The background could just as easily be applied to the body tag. There's a header div and a navigation div. Inside our navigation div we have our unordered list of items within our navigation. Finally, we have an empty div with a clear class which I'll get into later.

Now for some style...

body {
    font-family:Arial, Helvetica, sans-serif;
    font-size: .8em; margin:0; padding:0;
}

.clear {clear:both;}

#bg {
    margin:0px; padding:0;
    background-color:#E4EAF6;
}

These are some initial styles that aren't really all that special. I've set the text to Arial for the page, set the background color in my 'bg' div to blue and set up my clear class. The clear class just removes any floats that may be going on. This class should be applied on the first object after your floated object to ensure the proper spacing.

#header {
   position:relative;
   z-index:15;
   background: transparent url("test_bg.gif");

   height:80px; color:#3E4E5E;
   font-weight:bold;
   border-bottom: 1px solid #3E4E5E;
}

The items in bold are the necessary bits of information to accomplish the task. The rest is simply dressing. The relative positioning allows the z-index to take effect. The z-index raises the header above the navigation. Any value can be set, as long as it is higher than the z-index on the navigation. A background image is set with the colour set to transparent. The graphic is a GIF with transparency to allow the navigation to show through. (A great way to extend this would be to use a PNG with alpha transparency along with the hack to enable transparency in IE.)

#img ul { display:inline; list-style:none; }
#img li { float:left; }

The list is set to inline, the list markers are removed and each listed item is floated to the left so that the navigation appears left-to-right.

#img a {
   height:45px; width:130px; color:#3E4E5E;
   background: url("test_img.gif") no-repeat left top;
   background-color:transparent;
   background-position: 0 0;
   position:relative;
   margin-top: -10px;

   display:block;
   padding:14px 20px 5px 0px;
   font-weight:bold; font-size:85%;
   text-decoration:none;
   text-align:right;

   /* box model hack */
   voice-family: "\"}\"";
   voice-family:inherit;
   height:23px; width:105px;

}

The links themselves do all the fun stuff! The margin is set to -10 to shift the navigation up. The position is set to relative to allow the navigation to actually "appear" under the header. If you do not set the position to relative, as you shift the margin up, it'll appear to cut off your navigation.

The background image is declared and its position set to 0. Foreground and background colours are set to match.

The width is set to show enough of the background with padding and text alignment set so that the text appears in a decent location on the button. The bold section at the bottom is the box model hack which is applied to allow the navigation to appear correctly in IE5 and 5.5.

We could pretty much leave it at that but where's the fun in that? I've decided to add :hover and :active states as well.

#img a:hover {
   background-position: 0 -45px;
   padding:19px 20px 0px 0px;
}

#img a:active {
   background-position: 0 -90px;
   padding:19px 20px 0px 0px;
   color: #FFFFFF;
   background-color:#CC6600;
}

The hover state shifts the background so that the green button is now visible and appears slightly lower than before. The padding on top is adjusted to move the text down together with the button.

The active state maintains the same padding but the background is now shifted to show the orange button. The text colour is changed to provide enough contrast against the orange.

What's next?

While this looks okay, it has some drawbacks. Number one of which is it's ability to handle more or larger text. It's a fixed background so as more text is added or if resized too big, it will no longer fit within the graphic. The trick would be to come up with a Sliding Doors technique that could allow for the shifting. In addition, since the text is at the bottom, if the text is resized, it'd be nice to have to resize up and to the left instead of down and to the left as it is currently.

This was tested on Windows 2000 in IE5, IE5.5, IE6, Firebird 0.7 and Opera 7.

Update (Nov 28, 2003):

As it turns out, Sliding Doors of CSS, Part II details how to accomplish the resize issue that I mentioned above. It works in IE, however, with extra span tags to accomplish the feat. Don't like the extra span tags? I think there's a way around it: behaviours.

Published November 25, 2003 · Updated September 17, 2005
Categorized as HTML and CSS
Short URL: https://snook.ca/s/122

Want to learn about scaling CSS for large projects?

I'm available for full and half-day workshops on scalable CSS architecture. I can provide on-site training for your team. Interested?
Get in touch.