CSS Sliding Doors Gone Wild 9th July 2008

CSS Cross-Browser Horizontal Navigation
There are tons of tutorials on the web these days about how to develop a horizontal navigation menu, but few of them are very reliable across browsers when it comes to their CSS. Undoubtedly you have come across a tutorial that works great in Firefox and the most recent versions of Internet Explorer but if you look at IE6 and below things start to get weird. This tutorial will show you how to create a CSS cross-browser horizontal menu navigation very quickly and easily.

In this tutorial I am going to explain some of the pitfalls and offer you a solution for tabbed navigation that has been tested and will render exactly the same in IE5.5+, Firefox, Opera, Safari and Netscape. We will write only valid CSS level 2.1 for this demonstration. However, where things may be slightly different than other tutorials is the use of a small JavaScript snippet that helps to correct the anchored CSS image hover issue in IE5.5 and IE6. This is to correct the hover state of your tabs and force them to render correctly. The only problem is if the users JavaScript is turned off the hover will not work in those browsers, but it will still look like the tabs above.

A side note, this markup and CSS is designed for the Wordpress CMS and uses its built in CSS classes to define the current active page and show an active state. However, this will work for any CMS or system you currently implement. The only changes that need to be made are anywhere that “current_page_item” is used change it to reflect your CSS class (i.e. active). Everything will work just like before but now with your new classes for the currently active page.

Sliding Doors Gone Wild

Some of the ideas behind this technique come from Douglas Bowman’s article on the popular A List Apart web site titled “Sliding Doors of CSS.” However, where we differ is with the hover state. Obviously the CSS is different too and I like to think mine is a bit more modern because it allows your tabs to have state change, where as, the original Sliding Doors did not allow anything more than the active tab.

Semantic Markup

First you will need to create a .html or .htm file in your favorite editor (I prefer Dreamweaver CS3), then you will create a header <div> that will hold your navigation and next add an unordered list <ul> to hold the links inside the header. Below you will find the HTML markup for the menu.

<div id=”header”>
<ul id=”navigation”>
<li class=”current_page_item”>
<a href=”#”>Link</a>
</li>
<li><a href=”#”>Link</a></li>
<li><a href=”#”>Link</a></li>
<li><a href=”#”>Link</a></li>
<li><a href=”#”>Link</a></li>
<li><a href=”#”>Link</a></li>
</ul>
</div>

You’ll need to replace the href=”#” to point to the proper url and change the “Link” text to reflect the pages on your site. This simple code will create a very basic navigation list, but completely style free. If you loaded it in your browser you would see a very unattractive bulleted list of links. Don’t worry we will get to make it look nice in a few more steps.

The Images

CSS Navigation Example
As you can see here, portions of the images are hidden and only are displayed when the text size is made larger, making the tabs fluid and unbreakable for the most part.

I have included in the zip file an Adobe Photoshop tabs template where you can edit the gradients to match your site so you don’t have to try and rebuild the navigation from scratch, juts edit the color. You will need three images for the navigation to look like the example at the top of the page. Two images for the tabs (left and right), and an image for the navigation background, in this case it is a solid 1×1 pixel to give the navigation a bottom border and still allow the active tab to spill over and cover the border. Basically this will let you create a way to do what we did in our navigation, more about that later.

One more thing about the images before I move on to the CSS, when you save your image files make sure that the left image doesn’t have a transparency. What will happen is the right image will show through behind it and you will loose your rounded edge on the left side. I like to save both the images with a solid background color in that tiny space up in the corners so there isn’t any problems later. And now for the goods!!!

The CSS

* {
margin: 0;
padding: 0;
border: none;
outline: none;
line-height: 1em;
}
body {
font: 62.5% Verdana, Arial, Helvetica, sans-serif;
}

These are the basic CSS resets & styles for the wild card & body tags. The font is set to 62.5% to reset it to 10px and allow us to resize things using em’s where 1.2em would be 12px.

#header {
position: relative;
width: 100%;
height: 5em;
background: url(images/border-bottom.png) repeat-x bottom;
}

This block of CSS deals with styling the “header” division. The navigation is sitting inside of this header so we will set it to position: relative; which allows us to manipulate the the navigation to exactly where we want it down to the pixel. You can change the height to anything you want and the navigation will remain stuck to the bottom. However, if you use “em” the height will expand but if you use “px” to define the height it will remain constant while everything else expands. The background image is a 1×1 solid pixel that is repeated on the x axis to form a bottom border.

#navigation {
position: absolute;
bottom: 0px;
left: 0;
z-index: 999;
list-style: none;
}
* html #navigation {
bottom: 1px; /* Targets IE 5.5 only */
bo\ttom: 0px; /* Targets IE 6.0 only */
}

Now here is where the navigation style starts to take place. We first set position: absolute; to allow us to move our navigation around at will. Since the parent division (header) is relative the absolute position of the navigation is relative to that. Meaning bottom: 0; is the bottom of the header division and not the page. The z-index just make sure that nothing gets in the way of our navigation. We certainly don’t want something from another element leaking in and not allowing us to click a link. The * html #navigation portion just targets IE6 and 5.5 to set the position, otherwise there would be a crack in the navigation by one pixel in IE5.5. The first rule sets IE5.5 and fixes the problem and the second one sets it back for IE6 so it doesn’t break that browser.

#navigation li {
float: left;
margin-left: 2px;
background: url(images/right-tab.png) no-repeat 100% 0px;
font-size: 15px;
}

Here the <li> tag is getting styled. To make the standard vertical list into a horizontal one, we have to float each list item to the left. This will cause the list items to stack horizontally side by side. The margin on the left is to give your tabs some space between them. The background is set to no-repeat with a position that reads right top corner for those interested. The font is set to 15px and not 1.5em’s to allow browsers to shirk the font as well as expand it.

#navigation li a {
float: left;
display: block;
height: 2.4em; /* Targets IE 5.5 only */
hei\ght: 1.8em; /* All Other Browsers */
padding: 0.7em 1.5em 0em 1.4em;
background: url(images/left-tab.png) no-repeat 0% 0px;
color: #777;
text-decoration: none;
overflow: hidden;
}

This anchor <a> tag is floating left and set to block to allow the <li> tag to wrap around it and shrink to its size which is set to 1.8em for normal browsers and 2.4em for IE5.5. This has to do with the box model and how padding is handled in IE5.5. It’s a little out of the scope of this tutorial but rest assured that this make it look the same height as all the other browsers. The padding is top right bottom left and should be pretty self explanatory. It pushes the text into the middle for those who don’t know.

#navigation li.current_page_item {
background-position: 100% -150px;
}
#navigation li.current_page_item a {
background-position: 0% -150px;
color: #040404;
padding-bottom: 1px;
}
#navigation li:hover, #navigation li.ieHover {
background-position: 100% -150px;
}
#navigation li:hover a, #navigation li.ieHover a {
background-position: 0% -150px;
color: #040404;
}

These last set of selectors are mostly to position the tab images during resting, active and hover states. One important thing to note is when the padding on the bottom is set to 1px it will bypass the header image that acts as a bottom border for all the resting tabs and spill the active and hovering tabs beyond the edge of the division by 1px, which is just enough to cover up that bottom border. Everything else is just color or the position of an image. To demonstrate, if the image says 0% -150px it means all the way left and down 150 pixels to the top of the hover portion of the image. The reason the image is one and not two different images for separate states is because two images have a tendency to flicker. If you put the images together and utilize the positioning you can avoid any flickers in your sites images when they hover and it also loads faster.

The JavaScript

The only reason for this is to make IE6 and 5.5 hover.Otherwise you will have a menu that doesn’t change the position of the image and doesn’t properly function like we want it to. The JavaScript is very small and should go in the head of your document. If you don’t know what to do, there is a full working version of this menu that you can download below with the JavaScript implemented properly.

ieHover = function() {
var ieReplace = document.getElementById(”navigation”).getElementsByTagName(”li”);
for (var i=0; i
ieReplace[i].onmouseover=function() {
this.className+=” ieHover”;
}
ieReplace[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(” ieHover\\b”), “”);
}
}
}
if (window.attachEvent) window.attachEvent(”onload”, ieHover);

The Wrap Up & Download

So hopefully you read the post and found it interesting and are now downloading the files so you can edit the .psd file and change your colors and get started playing with your new menu. And hopefully you didn’t just skip my whole article and go straight for the goods. Anyhow, I hope this was informative and can solve a problem you were facing with your navigation. I know this is years of experience all wrapped up in a little neat little zip file all completed and ready to use, but me personally, I would miss getting my hands dirty. Anyhow, have fun and let me know if you launch a site using this navigation, I would enjoy seeing your take on it.

4 Responses to “CSS Sliding Doors Gone Wild”

  1. Derek Herman

    Aug 11, 08 at 3:54 pm

    Above I wrote “this markup and CSS is designed for the Wordpress CMS” which is partly true. What I mean is that in some cases where there is no active tab (archive page) the navigation will shift one pixel down. If you plan to use this type of navigation there are two approaches that will fix this issue. One is an alternative is to add a class .shift to the navigation on those pages like:


    #navigation.shift li a {
    border-bottom: 1px solid colorOfBorder;
    }
    #navigation.shift li:hover a, #navigation.shift li.ieHover a {
    border-bottom: none;
    }

    OR

    Remove the one pixel at the bottom of the navigation all together. However, using this technique will make it so you can fully blend the navigation with the color below it. We use the first option on this site. The navigation for Valen Designs is virtually identically to the code you get in the zip file above but missing the no active state fix. In later version we will fix the issue until then you can add the CSS above and if you have a question as to how to implement it feel free to ask.

  2. John

    Oct 16, 08 at 3:40 am

    great post thanks!

  3. Derek Herman

    Oct 16, 08 at 3:46 am

    Always glad to help.

  4. Simon

    Nov 12, 08 at 10:42 am

    great post thanks… I’m on a heavy deadline and was having trouble with the nav… This works great!


Leave a Reply