tags:

views:

270

answers:

3

When I have an <a> tag set to a specific image background like this:

HTML:
<a href="..." title="click here">Click Here</a>

CSS:
a {
  background: transparent url(button.png);
}

and I want the background to change whenever a user hovers over the spot, like this:

CSS:
a {
  background: transparent url(button_HOVER.png);
}

The hover background image flickers (takes about 1-2 seconds until it fully loads) when a user hovers over the link.

I could save the file as GIF and minify its size and loading time, but that would harm my specific image tremendously (it's big and highly graphical).

That's why I was looking for a better solution, such as perhaps counting on the browsers ability to cache images. Hence would I apply a style to a button like this:

CSS:
a {
  background: transparent url(button_HOVER.png);
  background: transparent url(button.png);
}

So that the image button_HOVER is first cached. It has seemingly affected the "flickering", but not completely. I thought of maybe creating a hidden tag with the HOVER image, so that maybe the result would be different.

Do you think there's a better way to solve it? (I emphasize I want to keep the file as PNG, it weighs 6-7k). Is my method efficient?

+1  A: 

You should search about this topic "preload images" You will find ways to preload images using css and javascript.
I believe that if you put a hidden image with source equal the src of png images you will use in the css files, this will make the images loaded when the page loads, and CSS work will be just switch preloaded images.

Amr ElGarhy
+7  A: 

Your solution would be to put both images (hover and active) in the same image file. Positioned on top of each other. Also known as Image Sprites. The browser will load the entire image file. On hover, you just change the background position.

Assuming the active image is at the top, and the hover image is positioned directly below that..your css code would be something like:

a.link {
  width:70px;
  height:24px;
  background: url(image.png) top no-repeat;
}
a.link:hover {
  background-position: bottom;
}

Notice background-position. Here I use top and bottom. You can specific exactly in pixels too. The entire image in this example would have a width of 70pixels and height of 48pixels. Some sites put all their small icons into one image. Loads altogether, save on requests too. :)

No need for preload scripts in this case.

Lyon
This is also a nice solution i agree with.
Amr ElGarhy
That's stupendous! Great solution I didn't think of, thanks a lot!
sombe
+2  A: 

The basic options available are to use an html element that's hidden from the viewer, or use javascript.

The html approach is probably the simplest, though:

<div id="preloadedImageContainer">
<img src="img/to/preload_1.png" />
<img src="img/to/preload_2.png" />
</div>

with the css:
#preloadedImageContainer {position: absolute; top: -1000px; left: -1000px; }

or, with javascript:

(function($) {
  var cache = [];
  // Arguments are image paths relative to the current page.
  $.preLoadImages = function() {
    var args_len = arguments.length;
    for (var i = args_len; i--;) {
      var cacheImage = document.createElement('img');
      cacheImage.src = arguments[i];
      cache.push(cacheImage);
    }
  }
})(jQuery)

the jQuery approach was lifted in its entirety from this page: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript.

Though the best approach would probably be, as Lyon suggests, css image sprites.

David Thomas