The Simplest Ways To Do Image Rollover Effects: JavaScript And CSS-Only

A common question on Yahoo! Answers is how to do image rollover effects simply.

There are two ways to do so: With JavaScript, and via CSS alone. Of the two, I prefer the JavaScript method, as it doesn’t require marking up your code too much; but the CSS method is fine, too, and takes away the worry of dealing with users who have disabled JavaScript in their browsers.

This topic also allows me to address the best way to “preload” images for use via JavaScript / CSS; previous articles I’ve written have used less efficient methods, and I’d like to go on record with the proper way to preload.

Last things first, then. The proper way to “preload” images is to use a standard XHTML img tag, using a CSS class to “hide” the image(s) being preloaded via display: none. These images should then appear directly before the closing body tag, to speed page loading by loading the “preloaded” images last.

img.hide {
        display: none;
        <img src="home-over.png" alt="" class="hide" />
        <img src="about-over.png" alt="" class="hide" />
        <img src="services-over.png" alt="" class="hide" />
        <img src="contact-over.png" alt="" class="hide" />

Using CSS to hide images should work for all current Web browsers, including versions 5+ of Internet Explorer.

CSS-Only Rollovers

You can create CSS-only rollovers. However, there are two drawbacks to this approach.

Because this method uses CSS, appearance problems may arise with various browsers, especially versions of Internet Explorer prior to version 8, but any browser that’s more than a couple years old could render things oddly.

The CSS only route basically replaces all rollover-effect img tags with div tags. Each such div receives a unique ID, so we can write CSS that targets just that item. Because of that, you cannot add alt attributes to your images; and this will affect their ability to index with image search engines. (Some people may see that as a benefit; but for those who want their images to index well, this method will likely seriously impede that desire.)

We first set the CSS properties of all the rollover div elements, fixing their display as inline-table. We do that because we want to ensure the image will flow into our layout; most Web browsers treat div elements as block elements, meaning that they appear as though they are followed by a br. That, generally speaking, will prevent our div-nee-img from lining up properly in most layouts.

#home, #about, #services, #contact, #leelee {
	display: inline-table;

Next, we fix the size of each div to be the same as the background image we will use, and make that background image the normal, or “up,” state of the image:

#home {
	width: 45px;
	height: 20px;
	background: #ddd url(images/home.png) no-repeat;

#about {
	width: 45px;
	height: 20px;
	background: #ddd url(images/about.png) no-repeat;

#services {
	width: 65px;
	height: 20px;
	background: #ddd url(images/services.png) no-repeat;

#contact {
	width: 60px;
	height: 20px;
	background: #ddd url(images/contact.png) no-repeat;

#leelee {
	float: left;
	padding-right: 10px;
	width: 154px;
	height: 300px;
	background: #fff url(images/leelee1.jpg) no-repeat;

To actually do the rollovers, we create a :hover pseudoclass effect, which changes the background of the given div to be the image we want shown on mouseover.

Note that not only can we change the height and width of the image, we can add or remove any effect we’d like, as well, such as changing the border color.

#home:hover {
	background: #ddd url(images/home-over.png) no-repeat;

#about:hover {
	background: #ddd url(images/about-over.png) no-repeat;

#services:hover {
	background: #ddd url(images/services-over.png) no-repeat;

#contact:hover {
	background: #ddd url(images/contact-over.png) no-repeat;

#leelee:hover {
	width: 200px;
	height: 300px;
	background: #fff url(images/leelee2.jpg) no-repeat;

And with that, we have CSS-only rollovers. You can see this in action here:

JavaScript Rollovers

The benefit of the JavaScript approach is that it uses actual images to achieve its rollover effects. However, this methodology requires you to add onmouseover and onmouseout event handlers to your rollover images’ tags; while that doesn’t mean more coding versus the CSS-only methodology, it does mean tinkering with XHTML source code, which some users might be reluctant to do for design / team development / WYSIWYG editor issues that may raise.

A way to avoid adding event handlers directly to your image tags is to use a library, such as jQuery, that allows you to add event handlers via JavaScript.

Under the JavaScript method, we again preload our images. And we then use img tags to place our “up-state” images wherever we want them to go.

We then add onmouseover and onmouseout event handlers to each tag. Using the reserved word this, which tells JavaScript we mean the image that is triggering the event, we change the image’s src attribute to be the path to whichever image we want to have displayed.

In the case of onmouseover, we want the “down-state” image to replace the “up-state” image; with onmouseout, we want the “up-state” image restored.

<img src="images/home.png" alt="Home" onmouseover="this.src='images/home-over.png'" onmouseout="this.src='images/home.png'" />
<img src="images/about.png" alt="About" onmouseover="this.src='images/about-over.png'" onmouseout="this.src='images/about.png'" />
<img src="images/services.png" alt="Services" onmouseover="this.src='images/services-over.png'" onmouseout="this.src='images/services.png'" />
<img src="images/contact.png" alt="Contact" onmouseover="this.src='images/contact-over.png'" onmouseout="this.src='images/contact.png'" />

<img id="leelee" src="images/leelee1.jpg" alt="Leelee Sobieski" onmouseover="this.src='images/leelee2.jpg'" onmouseout="this.src='images/leelee1.jpg'" />

And that’s all there is to that. You can see a working demo here:

I distribute all code under the GNU GPL version 3.

Leave a Reply

  • Check out the Commenting Guidelines before commenting, please!
  • Want to share code? Please put it into a GitHub Gist, CodePen or pastebin and link to that in your comment.
  • Just have a line or two of markup? Wrap them in an appropriate SyntaxHighlighter Evolved shortcode for your programming language, please!