Improved Navigation Image Replacement

Posted on April 27, 2007 in Tutorial | 1 Comment »

So my co-worker at work today was slicing a design, and the designer said that the navigation had to be images. Being the good little accessibility people that we were, we were trying to figure out a way to use images, but have text also show up when images are disabled.

So my co-worker went with the quick fix (for now), a JavaScript onmouseover solution, and I told him that it was lame. I told him there had to be a way to use CSS to do it. I didn’t have time to do it at work, so I played with it, and I have found a solution.

The Markup

Ok, so everyone knows to mark-up navigation in an unordered list:

<ul id="nav">
	<li><a href="#">Text to Cover Here</a></li>
	<li><a href="#">Text to Cover Here</a></li>
	<li><a href="#">Text to Cover Here</a></li>
	<li><a href="#">Text to Cover Here</a></li>
</ul>

Now, instead of placing an image in the anchor tag and then using JavaScript to change the hover state, I thought, why not just add an extra span at the end of the anchor tag. I chose the end, but it also works with it at the beginning. I think it makes more sense to have it at the end though, so that the text within the anchor tag is read first by screen readers and bots. So this is what our markup looks like now:

<ul id="nav">
	<li><a href="#">Text to Cover Here<span></span></a></li>
	<li><a href="#">Text to Cover Here<span></span></a></li>
	<li><a href="#">Text to Cover Here<span></span></a></li>
	<li><a href="#">Text to Cover Here<span></span></a></li>
</ul>

Let’s Style It

So I started off with just some normal styles that you would apply to a navigation: zeroing out margins and paddings, floating it, removing the list-styling, and giving it a width.

Next, I floated the list items so that they would be in a line horizontally. This is where it finally gets interesting, I promise. I styled the anchor tag like so:

ul#nav li a {
	background: #FFFF99;
	display: block;
	height: 30px;
	padding: 0 5px;
	width: 115px;
}

Since this is just an example, I put a random background color on (to make sure it didn’t show through in the final example), and I gave them all the same width. Not a likely situation, but I didn’t feel like giving each list item an id. That should be self explanatory enough.

Now, when I think back to the talk that Eric Meyer at An Event Apart Boston, he kept stressing that to a browser, an element is just an element, and you can do anything to it. So, my plan was to just set the anchor tag to be relatively positioned so that it would contain the span.

The next step is to add the background image to the span. Now one thing that needs to be realized is that you cannot use a transparent image. But I don’t think that really causes much of a problem in most cases.

ul#nav li a span {
	background: url(/wp-content/uploads/2008/01/nav.gif) no-repeat 0 -30px;
	cursor: pointer;
	display: block;
	height: 30px;
	left: 0;
	position: absolute;
	top: 0;
	width: 125px;
}

The only things to note from that is that I combined the normal and hover states into one awesome image (I wasn’t worried about how pretty it looked). I also had to add the cursor property for our best friend, IE6.

Ok, cool. We are on our way. Now we just need to shift the background image on the hover state:

ul#nav li a:hover span { background: url(/wp-content/uploads/2008/01/nav.gif) no-repeat 0 0; }

Voilà! It works like a charm. Check out the example.

But…

Did you check it in IE6? When I checked it in Firefox and IE7, everything worked beautifully. You can turn off the images and you get the text underneath.

When you do check it in IE6, you will notice that the hover states stay on. It’s very odd.

After a lot of tinkering, I finally found something that worked. If you add the following to the anchor when it is in its hovered state, it for some reason fixes it:

ul#nav li a:hover { background: 0 0; }

I have no explanation, but it does not seem to have any adverse affects on other browsers.

Let’s Bulletproof It

We can add a simple property to the anchor tag so that when someone resizes their text, it does not poke out from under the image:

ul#nav li a {
	background: #FFFF99;
	display: block;
	height: 30px;
	overflow: hidden; /*Added for bulletproofing*/
	padding: 0 5px;
	position: relative;
	width: 115px;
}

Check out the final example.

More Bulletproofing

If you wanted the text to resize gracefully when images are disabled, I suppose you could set your height in ems. Then you would just need to build some extra blank space into your image, so that it would work when images are enabled.

So hopefully that helps out my co-worker. I think it potentially solves a pretty big problem with CSS image navigation with images disabled.

Share This:
  • NewsVine
  • Technorati
  • Reddit
  • Google
  • StumbleUpon
  • Facebook
  • Digg
  • del.icio.us
  • Ma.gnolia
  • TwitThis

One Response

  1. Adrian TurnerApril 29, 2007 at 9:00 pm

    You know what this helps me out… after i spent an hour and a half fixing it on my own today jeesh man pick up the phone and call a dude…

    I’m reading this about and hour after fixing it myself, I had to go another route as my items were not equal in length.

    Thanks for looking into it though, but I told you I was going to fix that problem this weekend.

    By the way the reason that it took me so long is that I didn’t notice that my empty span was outside of my anchor tag.

Speak Your Mind

* Denotes Required Field

  1. Sick of filling out this form? Register or Log in now.

Who Am I?

Trevor Davis I’m Trevor Davis, a 24 year old Front-End Developer. Basically, I make web sites.

By day, I work for Matrix Group International in Alexandria, VA, and by night, I freelance.

Feel free to get in touch with me about anything.

What Have I Done?

  • Change We Can Believe In
  • Change We Can Believe In
  • Change We Can Believe In
  • Change We Can Believe In
  • Change We Can Believe In
  • Change We Can Believe In
  • Change We Can Believe In
  • Change We Can Believe In

View All My Work »

Bookmarks

  • Google Search Engine Optimization Starter Guide [PDF]

    Google has released a free 22-page Search Engine Optimization Starter Guide containing plenty of well-written, practical and straightforward advice for webmasters. If you've been looking into SEO for a while it probably won't contain anything new for you, but it's useful as a set of guidelines as to what Google considers to be good optimization practice. (psst, Google, with just a little design work it could have looked so much nicer!)

  • The importance of setting expectations

    To make your customer's experience better, be sure to set their expectations.

  • XML Sitemaps Generator

    Insert your URL and let it generate the XML sitemap for you. Very useful for static websites.

  • Train-ee ExpressionEngine Training

    Learn ExpressionEngine with books, screencasts, classroom training and free tutorials from Train-ee.com

  • web.without.words

    Weekly gallery of popular websites reconstructed by removing all words and images, replacing them with blocks.

View All My Bookmarks »