2

I have an image (in the top left as a home link), and I use the CSS :hover to change the image upon rollover.

The problem is, the image takes time to load the first time I rollover it. There's a temporary blank space, and you see the image incrementally load. It takes about a second, but it's annoying.

How can I fix this so the rollover is seamless? Is there a way to preload the image?

Pauly Dee
  • 441
  • 1
  • 7
  • 16
  • possible duplicate of [What is the best way to preload multiple images in JavaScript?](http://stackoverflow.com/questions/761263/what-is-the-best-way-to-preload-multiple-images-in-javascript) -- And acceptance rating is poor. ;-\ – Brad Christie Jan 02 '11 at 22:06

5 Answers5

4

There's two options I can think of, off-hand:

  1. css image sprites, or
  2. placing the :hover image in a hidden div elsewhere in the page.

1, sprites:

For a CSS Sprite, have one background image for the 'home' link, and simply change its position on the :hover:

#home {
    background-image: url(http://example.com/spriteOne.png);
    background-repeat: no-repeat;
    background-position: 0 100px;
}

#home:hover {
    background-position: 0 200px;
}

This does require set heights for the elements with the css-sprite background, though.


2, hidden preloading elements:

#home {
    background-image: url(http://example.com/bg.png);
    background-repeat: no-repeat;
    background-position: 0 100px;
}
#home:hover {
    background-image: url(http://example.com/hoverBg.png);
}
#preload,
#preload img {
    display: none;
}

<div id="preload">
    <img src="http://example.com/hoverBg.png" />
</div>
Community
  • 1
  • 1
David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • 1
    I think CSS sprites are definitely the way to go – James Long Jan 02 '11 at 22:13
  • @James, I'd tend to agree; it's rather cleaner than hard-coding lots of images into, essentially, a per-page cache system. On the other hand the requirement to know, beforehand, exactly how big each element is *permitted* to be can be restrictive (and certainly limits the scope for liquid layouts, albeit so does common sense, I suppose). – David Thomas Jan 02 '11 at 22:16
  • Although this is a really interesting solution, I wonder why no one suggested JavaScript...just saying...lol – JCOC611 Jan 02 '11 at 22:17
  • @JCOC611: my own explanation for that is because I feel that using JS needlessly complicates things, plus: I'm not *that* good at vanilla JS... =/ – David Thomas Jan 02 '11 at 22:19
  • lol, in my point of view, doing this with plain CSS is kinda more complex than JavaScript, but that's because I love JavaScript! XD – JCOC611 Jan 02 '11 at 22:21
  • 1
    Go with sprites. It reduces the number of http requests required which might not sound like a big deal until you try to view your page over a small pipe. – chprpipr Jan 02 '11 at 23:18
1

A method that I have found works really well for rollovers is using CSS sprites, i.e. using an image that contains both the original and rollover versions of the image. That way both versions load at the same time, and changing between them is just a matter of changing the background-position style.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

One way to do it is to add an invisible image to your page, with the same URL. So by adding the following to the beginning of the documents body, you actually instruct the browser to load this image as soon as possible.

<IMG src="rolloverImage.png" style="display:none">

While this tag remains a part of your document, it is not shown or even rendered because of the "display:none" settings. You can even listen to its load event and remove the tag completely from the DOM once it is loaded, to keep the "garbage" out of the document. Once an image is loaded to memory, it is automatically reused every time you refer to the same URL, so once you set the source of the other image to the same URL, it will be loaded from memory.

Hope that helps, Kobi

Kobi Hari
  • 1,259
  • 1
  • 10
  • 25
1

1. Answer: Use CSS Sprites

2. Answer: Or create something like this:

<a href="link.html">

<!-- Remove this img-tag if you don't have a 'nohover' background -->
<img alt="image" src="images/image.png" class="nohover" />

<img alt="imagehover" src="images/image.png" class="hover" />

</a>

And the CSS:

img.nohover {

border:0

}

img.hover {

border:0;

display:none

}

a:hover img.hover {

display:inline

}

a:hover img.nohover {

display:none

}

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Arxisos
  • 2,719
  • 20
  • 21
0

Put the image in a div with a style set to { height: 0; overflow: hidden; }, that should make the browser preload the image.

grivescorbett
  • 1,605
  • 1
  • 21
  • 29