Mouseover Image Replacing

Mouseover Image Replacing






Note

We are no longer accepting new customers or work orders at this time. Thank you for your interest.


The best feeling buttons on the Web are created as graphic images which respond in some way when the visitor points their mouse at the image - usually by changing to another (similar) image, with bigger words, or highlighting, or more shadow (or less shadow), or a different background color, etc.

But what is the best way to implement this kind of behavior?

First Way

The first way to do it is with Javascript. Most tags have event handlers "onmouseover" and "onmouseout", which can call a Javascript function of your choice, when the user mouses "over" the item, or mouses away (out) from it.

This works fairly well, although it requires some Javascript, which can result in browser-specific issues, and is often difficult and very slow to debug.

When I go this route, I usually save my Javascript code with a README file so I can plug it right into the next web site that needs it. Just tweak a few site-specific things and it's working.

One problem you'll encounter if you've never implemented this before is, since you have to have separate images for the "regular" and "highlight" versions of the buttons, usually the regular button loads when the web page loads; but then the hilighted version does not load until it's actually required - when the visitor mouses over the regular image - causing their browser to start new query to the web server, to get that image! This results in a delay (often of 3-4 seconds!), so the button doesn't respond very fast to the mouse-over, which looks and feels wrong. (once the image is loaded into the browser's cache, it will redraw fast, causing the visitor to say "hm, the web is slow today" when it's really not).

Often a work around for that is more javascript code - write a function to pre-load all the images you'll need later, and make the BODY tag do an "onload" to call that new function that loads all the images. This all works, it's just the "old" way of doing things.

Another down side is, some people disable Javascript in their browsers. These are probably the same people that think there are still security issues with Javascript (probably the same people who disabled Cookies as well). Both Javascript and Cookies are secure now, and have been for a long time. People need to get used to upgrading to the latest versions of their web browsers on a regular basis, just in the event that future bugs are discovered and fixed by the vendors.

Second Way

CSS has been getting more powerful over time. More and more browsers support a richer and richer set of CSS features as time goes on.

You can actually do this whole image-switching-on-mouseover thing completely in CSS!

The idea here is to use the pseudo-attribute :hover to specify the different style settings you want to occur when the visitor mouses over the particular item in the browser's window.

Browser Compatibility

One of the harder things to accomplish when debugging code like this is to make it work in all the modern browsers today. I generally check my web sites with the following browsers:

Generally, if it works in IE 6 and Firefox, it will work everywhere else. I almost never have difficulty with Javascript or CSS in Safari or Opera, after debugging for hours in IE and Firefox.

New Technique - Sliding Images

This is where you use a single image containing both the regular and hilighted versions of the image at once. This has many advantages. You do not have to preload anything (less Javascript!) The "highlighted image" is instantly available at all times, because it's part of the regular image.

Example

For example, let's say that you have a left navigation bar that's 150 pixels wide, and the button images for the leftnav bar are the full 150 px wide. You're actually going to create image files that are 300 pixels wide, and put the "regular" image on one side, and the "highlight" image on the other side. Now all you have to do is draw half the image at a time. This is where CSS comes in to play.

CSS has an interesting concept of a Background Image:

background-image: url(/local/path/to/image.gif);
            

If a background image is drawn in a container larger than the image, it will repeat itself over and over, both in the horizontal and vertical directions. Yes, you can turn off this repeating feature, but there's no need for our application - our container will always be smaller or equal to the size of the background image.

If a background image is drawn in too small a container, it is chopped off to the right and bottom (by default) in order not to draw outside the container. This is good - we want to use this feature to our advantage.

Background images can also have a specified "position". The default position is 0,0 which means the upper-left corner of the image should be shown in the upper left corner of the container it's being drawn in. We can control this with the CSS attribute

background-position: x y;
            

where 'x' and 'y' should really be integer numbers (in pixels). Note, there's no comma between the x and y values here. And yes, x or y may be a negative value, not just positive!

You really do have a lot of control over the background image, as you can see.

Browser Compatibility Issues

As you might have worried, there's a lot of variation in how browsers implemented the pseudo-attribute ":hover", which we depend heavily in this trick. The biggest offender is IE 6, wherein :hover will only work on anchor (a) tags! This causes a lot of problems for us, but luckily we can make it work anyway.

Coding It

For the sake of simplicity, I am combining styles and drawing in the same file. I never develop web sites this way, but it's much easier when testing and debugging a new idea like this, something I've never done before.

Note how there is no Javascript, nor did this have to be written in any sort of high-level language (PHP, Perl CGI, etc.). It's just plain old HTML.

<html>
<head>
<style>
.leftnav { font-family: verdana,geneva,sans-serif; }
.leftnav a div { width: 150px; height: 49px; position: relative; background-repeat: no-repeat; background-position: 0 0; }
.leftnav .services a div { background-image: url(/img/leftnav-services.gif); }
.leftnav .questions a div { background-image: url(/img/leftnav-questions.gif); }
.leftnav a:hover div { background-position: -150 0; } /* for IE and Firefox */
.leftnav a:hover { background-position: -150 0; } /* for IE 6 */
.leftnav .marker { background-color: orange; width: 10px; height: 49px; position: relative; }
</style>
</head>
<body>
<div class=leftnav>
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td><div class=services><a href="/index.php/home/"><div></div></a></div></td>
<td><div class=marker></div></td>
</tr>
<tr>
<td><div class=questions><a href="/index.php/home/faq/"><div></div></a></div></td>
<td><div class=marker></div></td>
</tr>
</table>
</div>
</body>
</html>
            

For however many buttons you want in your navigation bar, you must create the images for them, and duplicate the CSS line that starts with:

.leftnav .services a div { ... };
            

You can see there were 2 buttons already set up, above ("services" and "questions"). The "marker" lines are for a hilighting image that marks which selection the person is currently viewing. You might need PHP or another high-level language to display the marker only on the currently active line, if that's a feature you want.

The only reason a table was used here was to make the "markers" reside just to the right of each navigation button. If you don't want markers, you can remove the entire table, and just list the DIV tags for each navigation button one after the other, i.e.:

<div class=services><a href="/index.php/home/"><div></div></a></div>
            

Sample Image

Here's a sample image with both the regular and hilighted parts built into it. Note that I had reversed them in this example (the regular one's on the right, and hilighted's on the left). All you have to do to use this image with the code above is to change all "-150 0" lines to read "0 0", and change the "0 0" line to read "-150 0".

(only half of this image is displayed at any given time)



Bookmark and Share


Don't miss the latest web tips and tricks!
Subscribe to our low-volume mailing list:

Privacy Policy

See other tricks:  Web/PHP | Unix/Linux | Perl | SQL | General


Sample Sites | Customers | Our Team | Contact Us | Tips and Tricks | Tools | Our Network | Home

Copyright © 2006 - 2010 Keith Smith Internet Marketing LLC, all rights reserved.
Problem with this web site? please let us know