kmcm

Web Development with PHP, HTML, CSS, & JavaScript

Using Images in Navigation

Monday 11th May 2009

In designing websites, one of more artistic ways to make a site more interesting to the user is to employ the use of images, as opposed to plain text. One particular area where this can be effective is in navigation elements. There are a number of different techniques employed in creating beautiful, image based navigation elements. Unfortunately no one technique is perfect and each has their shortcomings.

Static images

Probably the easiest way to add images to the navigation in your site is to use the <img> tag in your mark-up. Within your list of links (if your navigation isn’t in a list, you’re doing something wrong), place <img> tags, which reference the images you want to use for each navigation element.

<li>
<a href="”services”">
<img src="”images/nav-image-01.jpg”" alt="”services”" />
</a>

</li>

The drawbacks with this technique are that it may take a while for all your images to load, giving users an unattractive introduction to your site, also you can’t provide a hover state to your images, and you are left with a blank navigation area when images are turned off.

Image pre-loading

An old technique that a lot of developers choose is to use CSS to display images for links. To add interactivity that can’t be achieved with the Static Images example, a second image is created, and this is displayed when the user hovers over one of the links.

a { 
background:(images/nav-image-01.jpg);
}

a:hover {
background:(images/nav-image-02.jpg);
}

There is a small but important problem with using CSS to do this, which is that the hover images don’t actually load until the links themselves are hovered over. This is because CSS images are only loaded as they are needed. This means that when the links are hovered over for the first time there is a slight delay while the image is loaded, for which time the link has no background image. In some cases this would be hardly noticeable, but can result in an amateurish looking site when it is.

The way many developers counter act this delay is to use a small piece of Javascript code, which loads all images from the CSS file before the page is displayed. This prevents the “blank” background delay, but is dependent on Javascript being enabled in the user’s browser.

CSS images

This is a pure CSS technique, which removes the need for the Javascript code from the previous example. Instead of having 2 separate background images for your links, here you combine the two images into the one (like a sprite), and display a different part of this single larger image depending on whether the user is hovering over the element or not.

a {
display:block;
width:100px;
height:45px;
background: url(images/nav-image-03.jpg);
}

/*change the position of the background image*/
a:hover {
background-position: 0px -45px;
}

This is a simplistic and efficient (one image has less loading overheads than two, plus there is no need for JS) alternative way to avoid image preloading, and has become a more prevalent technique than the previous one.

What about the Link Text?

One of the drawbacks to using Image Based Navigation is the problem of your link text. You need users to be able to read your links regardless of whether they have Javascript enabled, CSS images on, no stylesheet, or indeed are using alternative user agents.

The Alt Attribute

If you’re using html images to display your navigation graphics, you can provide a text alternative for these images using the Alt Attribute in your <img> tag. This ensures that users with screen readers can extract the link text, users with CSS images off and no CSS will still see your images, although this technique comes at a cost to the interactivity of the site, with the inability to create dynamic hover state changes.

The Title Attribute

When you use CSS to power your image based navigation, you don’t have the alt attribute of an image tag to rely on, so you need to cater for users another way. One such way is to add the link text to the Title Attribute of the <a> tag. Many modern web browsers use the contents of the Title Attribute as a tooltip for the link, and although the text will not be displayed when users have CSS images turned off or no CSS enabled, it will be read by screen readers when the link itself is empty.

Text-indent

If you need your link text to be seen by users who have CSS turned off, you can add the link text to the a tag, and then use the text-indent property in CSS to effectively move the link text off the screen, so the user doesn’t see it.

a {
text-indent: -9999px;
}

This means that with no CSS, users will be shown the link text, and there is some (although inconsistent) support of this property in screen readers. This solution, like the previous one, doesn’t work well with CSS images turned off. Another problem with this method is that the link outline will stretch to cover the entire link, including the text, which can result in large outline that stretches away off the screen, looking a bit ugly and potentially confusing the user.

Display: none;

This technique is very similar to the previous one, although here we use a little more mark-up and the CSS display: none; property to hide the text. By adding a tag inside our link, we can add text to our link and set the CSS property of display: none;

a span {
display:none;
}

What this does is the same as the previous example, although we are spared the unsightly large outline box for links on focus, coming at the expense of the extra html code.

It is worth noting that all the solutions above can be adequate techniques depending on your requirements, and indeed none of the above is the perfect solution for every issue. There are a number of variants on the above techniques floating around on the web, all of which toy with extra mark-up and ways to hide text. Where possible, I would recommend a mixture of text and image based navigation, whereby the link text is shown over a CSS background with hover states. This seems to me to provide the best of both worlds. Which technique you choose is up to you.

Filed under: