Changing image on hover with CSS/HTML

I have this problem where I have set an image to display another image when the mouse hovers over, however the first image still appears and the new one doesn't change height and width and overlaps the other one. I'm still pretty new to HTML/CSS so I may have missed something simple. Here is the code:

<img src="LibraryTransparent.png" id="Library">
#Library {
height: 70px;
width: 120px;
}


#Library:hover {
background-image: url('LibraryHoverTrans.png');
height: 70px;
width: 120px;
}
658954 次浏览

The problem is that you set the first image through 'src' attribute and on hover added to the image a background-image. try this:

in html use:

<img id="Library">

then in css:

#Library {
height: 70px;
width: 120px;
background-image: url('LibraryTransparent.png');
}


#Library:hover {
background-image: url('LibraryHoverTrans.png');
}

One solution is to use also the first image as a background image like this:

<div id="Library"></div>
#Library {
background-image: url('LibraryTransparent.png');
height: 70px;
width: 120px;
}


#Library:hover {
background-image: url('LibraryHoverTrans.png');
}

If your hover image has a different size, you've got to set them like so:

#Library:hover {
background-image: url('LibraryHoverTrans.png');
width: [IMAGE_WIDTH_IN_PIXELS]px;
height: [IMAGE_HEIGHT_IN_PIXELS]px;
}

Change the img tag to a div and give it a background in CSS.

Use content:

#Library {
height: 70px;
width: 120px;
}


#Library:hover {
content: url('http://www.furrytalk.com/wp-content/uploads/2010/05/2.jpg');
height: 70px;
width: 120px;
}

JSFiddle

You can't use CSS to change image SRC attributes (unless the browser supports it). You may want to use jQuery with the hover event.

$("#Library ").hover(
function () {
$(this).attr("src","isHover.jpg");
},
function () {
$(this).attr("src","notHover.jpg");
}
);

check this fiddle

I think the image path may be wrong in your case

the syntax looks right

background-image:url('http://www.bluecowcreative.ca/wp-content/uploads/2013/08/hi.jpg');

In the way that you're doing things, it won't happen. You're changing the background image of the image, which is being blocked by the original image. Changing the height and width also won't happen. To change the src attribute of the image, you would need Javascript or a Javascript Library such as jQuery. You could however, change the image to a simple div (text) box, and have a background image that changes on hover, even though the div box itself will be empty. Here's how.

<div id="emptydiv"></div>


#emptydiv {


background-image: url("LibraryHover.png");
height: 70px;
width: 120px;

}

#emptydiv:hover {


background-image: url("LibraryHoverTrans.png");
height: 700px;
width: 1200px;


}

I hope this is what you're asking for :)

What I usually do is that I create a double image with both states, acting like kind of a two-frame film which I then use with as background for the original element so that the element has width / height set in pixels, resulting in showing only one half of the image. Then what the hover state defines is basically "move the film to show the other frame".

For example, imagine that the image has to be a gray Tux, that we need to change to colorful Tux on hover. And the "hosting" element is a span with id "tuxie".

  1. I create 50 x 25 image with two Tuxes, one in color and other gray,
  2. then assign the image as a background for a 25 x 25 span,
  3. and finally set the hover to simply move the background 25px left.

The minimal code:

<style>
#tuxie {
width: 25px; height: 25px;
background: url('images/tuxie.png') no-repeat left top;
}
#tuxie:hover { background-position: -25px 0px }
</style>


<div id="tuxie" />

and the image:

Two-frame Tuxie "film"

Advantages are:

  • By putting both frames in one file, it's ensured that they are loaded at once. This avoids the ugly glitch on slower connections when the other frame never loads immediately, so first hover never works properly.

  • It may be easier to manage your images this way since "paired" frames are never confused.

  • With smart use of Javascript or CSS selector, one can extend this and include even more frames in one file.

    In theory you could put even multiple buttons in single file and govern their display by coordinates, although such approach could get quickly out of hand.

Note that this is built with background CSS property, so if you really need to use with <img />s, you must not set the src property since that overlaps the background. (Come to think that clever use of transparency here could lead to interesting results, but probably very dependent on quality of image as well as of the engine.).

You can replace the image of an HTML IMG without needing to make any background image changes to the container div.

This is obtained using the CSS property box-sizing: border-box; (It gives you a possibility to put a kind of hover effect on an <IMG> very efficiently.)

To do this, apply a class like this to your image:

.image-replacement {
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: url(http://akamaicovers.oreilly.com/images/9780596517748/cat.gif) no-repeat;/* this image will be shown over the image iSRC */
width: 180px;
height: 236px;
padding-left: 180px;
}

Sample code: http://codepen.io/chriscoyier/pen/cJEjs

Original article: http://css-tricks.com/replace-the-image-in-an-img-with-css/

Hope this will help some of you guys who don't want to put a div to obtain an image having a "hover" effect.

Posting here the sample code:

HTML:

<img id="myImage" src="images/photo1.png" class="ClassBeforeImage-replacement">

jQuery:

$("#myImage").mouseover(function () {
$(this).attr("class", "image-replacement");
});
$("#myImage").mouseout(function () {
$(this).attr("class", "ClassBeforeImage-replacement");
});

Another option is to use JS:

<img src='LibraryTransparent.png' onmouseover="this.src='LibraryHoverTrans.png';" onmouseout="this.src='LibraryTransparent.png';" />

With everyones answer using the background-image option they're missing one attribute. The height and width will set the container size for the image but won't resize the image itself. background-size is needed to compress or stretch the image to fit this container. I've used the example from the 'best answer'

<div id="Library"></div>
#Library {
background-image: url('LibraryTransparent.png');
background-size: 120px;
height: 70px;
width: 120px;
}


#Library:hover {
background-image: url('LibraryHoverTrans.png');
}

try one of them

<img src='images/icons/proceed_button.png' width='120' height='70' onmouseover="this.src='images/icons/proceed_button2.png';" onmouseout="this.src='images/icons/proceed_button.png';" />

or if you using image as a button in form

<input type="image" id="proceed" src="images/icons/proceed_button.png" alt"Go to Facebook page" onMouseOver="fnover();"onMouseOut="fnout();" onclick="fnclick()">
function fnover()
{
var myimg2 = document.getElementById("proceed");
myimg2.src = "images/icons/proceed_button2.png";
}


function fnout()
{
var myimg2 = document.getElementById("proceed");
myimg2.src = "images/icons/proceed_button.png";
}

The problem with all the previous answers is that the hover image isn't loaded with the page so when the browser calls it, it takes time to load and the whole thing doesn't look really good.

What I do is that I put the original image and the hover image in 1 element and hide the hover image at first. Then at hover in I display the hover image and hide the old one, and at hover out I do the opposite.

HTML:

<span id="bellLogo" onmouseover="hvr(this, 'in')" onmouseleave="hvr(this, 'out')">
<img src="stylesheets/images/bell.png" class=bell col="g">
<img src="stylesheets/images/bell_hover.png" class=bell style="display:none" col="b">
</span>

JavaScript/jQuery:

function hvr(dom, action)
{
if (action == 'in')
{
$(dom).find("[col=g]").css("display", "none");
$(dom).find("[col=b]").css("display", "inline-block");
}


else
{
$(dom).find("[col=b]").css("display", "none");
$(dom).find("[col=g]").css("display", "inline-block");
}
}

This to me is the easiest and most efficient way to do it.

Just use Photoshop and create two of the same image, the 1st one being how you want it to look, the 2nd being how you want it to look when it's hovered over. I'm wrapping the image in an <a> tag, because I'm assuming that it's what you want. For this example I'm doing a facebook icon which is desaturated, but when hovered over it will show the blue color of facebook.

<a href="www.facebook.com"><img src="place of 1st image" onmouseover="this.src='place of 2nd image'" onmouseout="this.src='place of 1st image'"></a>

My jquery solution.

function changeOverImage(element) {
var url = $(element).prop('src'),
url_over = $(element).data('change-over')
;


$(element)
.prop('src', url_over)
.data('change-over', url)
;
}
$(document).delegate('img[data-change-over]', 'mouseover', function () {
changeOverImage(this);
});
$(document).delegate('img[data-change-over]', 'mouseout', function () {
changeOverImage(this);
});

and html

<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=%3Cimg%20original%20/%3E&w=342&h=300" data-change-over="https://placeholdit.imgix.net/~text?txtsize=33&txt=%3Cimg%20over%20/%3E&w=342&h=300" />

Demo: JSFiddle demo

Regards

Live Example: JSFiddle

The Accepted answer has some problem. The image wasn't resized there. Use background-size property for resizing the image.

HTML:

<div id="image"></div>

CSS:

#image {
background-image: url('image1');
background-size: 300px 390px;
width: 300px;
height:390px;
}


#image:hover{
background: url("image2");
background-size: 300px 390px;
}

.foo img:last-child{display:none}
.foo:hover img:first-child{display:none}
.foo:hover img:last-child{display:inline-block}
<body>
<a class="foo" href="#">
<img src="http://lojanak.com/image/9/280/280/1/0" />
<img src="http://lojanak.com/image/0/280/280/1/0" />
</a>
</body>

.hover_image:hover {text-decoration: none} /* Optional (avoid undesired underscore if a is used as wrapper) */
.hide {display:none}
/* Do the shift: */
.hover_image:hover img:first-child{display:none}
.hover_image:hover img:last-child{display:inline-block}
<body>
<a class="hover_image" href="#">
<!-- path/to/first/visible/image: -->
<img src="http://farmacias.dariopm.com/cc2/_cc3/images/f1_silverstone_2016.jpg" />
<!-- path/to/hover/visible/image: -->
<img src="http://farmacias.dariopm.com/cc2/_cc3/images/f1_malasia_2016.jpg" class="hide" />
</a>
</body>

To try to improve this Rashid's good answer I'm adding some comments:

The trick is done over the wrapper of the image to be swapped (an 'a' tag this time but maybe another) so the 'hover_image' class has been put there.

Advantages:

  • Keeping both images url together in the same place helps if they need to be changed.

  • Seems to work with old navigators too (CSS2 standard).

  • It's self explanatory.

  • The hover image is preloaded (no delay after hovering).

Here is the simple trick. Just copy and paste it.

<!DOCTYPE html>
<html lang="en">
<head>
<title>Change Image on Hover in CSS</title>
<style type="text/css">
.card {
width: 130px;
height: 195px;
background: url("../images/card-back.jpg") no-repeat;
margin: 50px;
}
.card:hover {
background: url("../images/card-front.jpg") no-repeat;
}
</style>
</head>
<body>
<div class="card"></div>
</body>
</html>

What I would recommend is to use only CSS if possible. My solution would be:

HTML:

<img id="img" class="" src="" />

CSS:

img#img{
background: url("pictureNumberOne.png");
background-size: 100px 100px;
/* Optional transition: */
transition: background 0.25s ease-in-out;
}
img#img:hover{
background: url("pictureNumberTwo.png");
background-size: 100px 100px;
}

That (not defining the src attribute) also ensures that transparent images (or images with transparent parts) are shown correctly (otherwise, if the second pic would be half-transparent, you would also see parts of the first picture).

The background-size attribute is used to set the height and width of a background-image.

If (for any reason) you don't want to change the bg-image of an image, you could also put the image in a div-container as following:

HTML:

<div id="imgContainer" class="">
<img id="" class="" src="" />
</div>

... and so on.

I had a similar problem.

With my button defined like:

<button  id="myButton" class="myButtonClass"></button>

I had the background styling like this:

#myButton{ background-image:url(img/picture.jpg)}


.myButtonClass{background-image:url(img/picture.jpg)}


.myButtonClass:hover{background-image:url(img/picture_hover.jpg)}

When I switched it to:

#myButton{}


.myButtonClass{background-image:url(img/picture.jpg)}


.myButtonClass:hover{background-image:url(img/picture_hover.jpg)}

The hover over feature worked just fine.

(not addressing other attributes like size and position of image or of container, just the background image changing)

Use "content:;" at the hover.This works.