CSS Roll-overs with image replacement

When creating a menu or header text the client may wish for a font or effect not possible using standard web approaches. This maybe a drop shadow, gradient, glow or simply a non standard web font. In most cases an image will look softer and in most peoples view better looking than standard browser generated text ( although I do have a soft spot for the natural simplicity of text!) . But lets say for arguments sake you have to look at replacing text with images.

Our HTML menu

So at the moment our HTML menu uses an unordered list to contain our menu items, h3 tags for importance and seo, and a link tag to make the text a link to the relevant page.

<ul>
<li><h3 id="contact_menu" ><a href="Contact" >Contact</a></h3></li>
</ul>

Hiding the Text

So the first thing we are going to do is use CSS to hide our text and use an image instead. This is done by setting the height of the link we will use to 0px, then adding the image we plan to use height in as padding instead. We will also set our a link to display block and hide any overflow.

h3.rollreplace a{
 padding: 40px 0px 0px 0px;
 background-repeat: no-repeat;
 height: 0px !important; /* for most browsers */
 height /**/:40px; /* for IE5.5's bad box model */
 display: block;
 overflow: hidden;
}

Search Engines

So at the moment we are using tags to keep search engines happy and to help show the correct importance of our text. If we are now going to replace this with

<h2/><img src="contact.png" alt="contact image" /></h2/>

we may think the alt tag will come to our rescue for SEO and screen readers. Well it will will for screen readers and it might a little for seo, but can we be sure? A trick used for many years is an approach developed to actually still use the text version but swap out the text using CSS for an image. The idea is everything is already there for SEO, but CSS will then render our image so it looks as we now desire for real people viewing the site and not Search Engine bots.

So our HTML and CSS now looks like this…

<ul>
<li><h3 id="contact_menu" class="rollreplace" ><a href="Contact" >Contact</a></h3></li>
</ul>
h3.rollreplace a{
 padding: 40px 0px 0px 0px;
 background-repeat: no-repeat;
 height: 0px !important; /* for most browsers */
 height /**/:40px; /* for IE5.5's bad box model */
 display: block;
 overflow: hidden;
}

h3#contact_menu a{
 background-image: url("contact.png");
 width:112px;
}

Swap image on hover.

So now when someone rolls over our image we want to swap it out for lets say another version of a different colour.

To do this we have already made the image a link, so we can use CSS a:hover. Had we not used CSS for this we could of used Javascript, but try and use CSS where possible if you want to cater for those with JS disabled. Now we could use another image and replace it on hover, however a better more efficient practice is to use the same image as the original, but it contains both versions and we simply move the element of the image we require for the hover part. So in our case our image was 40 pixels in height, so now its 80px in height for both images and we move it 40px down…

h3#contact a:hover{
 background-position: 0px -40px;
 width:112px;
}

The image looks like this…
contact image example

This method is preferred over using a separate image as it reduces the need to load 2 images from the server and will remove any flickr or gap between loading the original and replacement image when a visitor hovers over the link.