Heiko Mamerow

Web development with WordPress

Preload CSS background image with CSS

If a CSS background image is to change on mouseover, there is always an unsightly loading delay on the first hover. Because the hover image must first be loaded by the browser.

Hover example
loading delay on first hover
Hover example
loading delay on first hover

To make the hover image visible on the first mouseover without delay, it must be preloaded.

Normally the image could be preloaded with a link element of type preload. This would require some work for us, because we would have to write a PHP function to do this and hook this with wp_head().

Another solution would be with CSS sprites. But even that is mostly complex, because we would have to put the images together first.

Luckily there is a much easier to implement solution with pure CSS: We load the hover image by embedding it “secretly”.

I will explain this by an example. Imagine we have a small div box with a background image. On mouseover the background image should change.

// This icon will load immediately.
.icon-box {
    background-image: url('icon.svg')

// This icon will load at the first hover.
.icon-box:hover {
    background-image: url('icon-hover.svg')

In our browser only the icon.svg will load after the CSS is finished. The icon-hover.svg will load after the first hover.

Loading of the hover image takes time. And during this time we see normally no image and have an little “flash effect”.

Now we add some CSS which preloads the image.

// Preload the hover icon.
.icon-box::after {
    content: url('icon-hover.svg');
    height: 0;
    overflow: hidden;
    position: absolute;
    width: 0;
    z-index: -1;

Just add an CSS pseudo-element to our .icon-box, (pre-)load the background image as content and hide this element safely. Now the hover image is also loaded the same as the other image.

Big credits for the funny emojis above:
Emoji One, CC BY-SA 4.0, via Wikimedia Commons
Emoji One, CC BY-SA 4.0, via Wikimedia Commons

Leave a Reply

Your email address will not be published. Required fields are marked *