Changing image on hover with CSS/HTML
Solution 1
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;
}
Solution 2
Another option is to use JS:
<img src='LibraryTransparent.png' onmouseover="this.src='LibraryHoverTrans.png';" onmouseout="this.src='LibraryTransparent.png';" />
Solution 3
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".
- I create 50 x 25 image with two Tuxes, one in color and other gray,
- then assign the image as a background for a 25 x 25 span,
- 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:
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.).
Solution 4
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;
}
Solution 5
.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).
Related videos on Youtube
user2704743
Updated on July 05, 2022Comments
-
user2704743 almost 2 years
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; }
-
user2704743 over 10 yearsThanks, what do I need to change to fix this problem?
-
user2704743 over 10 yearsthanks, will this also change the height and width of the new image on hover?
-
Aurelio De Rosa over 10 yearsIf your hover image has a different size, you have to write them.
-
user2704743 over 10 yearsyour solution worked with the hover but the size of the images hasn't changed?
-
Tomzan over 10 yearsDo you want it to change? if yes just add to :hover class the right size.
-
user2704743 over 10 yearsI tried your solution exactly as shown, for some reason though the sizes aren't changing, the hover works though
-
user2704743 over 10 yearsyes I read the update, so i changed my img tag to div, then copied down what you have here. it fixed the hover but neither the first image or hover image are changing sizes i'm not sure why?
-
Aurelio De Rosa over 10 yearsNo, I meant the "If your over image has a different size, you've to set them like so:" part...
-
user2704743 over 10 yearsmy image is within a link tag does this have an effect on anything?
-
user2704743 over 10 yearshi I've been trying this solution, it fixes the hover issue but doesn't fix the sizes they stay the same what can I do?
-
Daniel Schwarz over 10 yearsSeems to be working for for me. Can we see your code? Here's mine: jsfiddle.net/kHBzh
-
m02ph3u5 over 8 yearsThis requires javascript; didn't OP ask for a css/html solution?
-
Lombas almost 8 yearsI think this is the best solution. It's simpler, uses the proper <img> tag, and doesn't have to worry with background-repeat and stuff like that.
-
piyushj almost 8 yearsadd some description/comments to it, simply posting code wont help
-
the digitalmouse almost 8 yearsAnd while this is resurrecting an old solution, it is really a bad practice to embed styles with the HTML. All style info should be included at the top of the HTML file inside style tags, or linked from an external stylesheet.
-
jagb about 7 years+1 for using "sprites", Sprites are making pages load faster, a good online tool that can help creating sprites for an existing website is SpriteMe, it's very useful to create sprites faster as it will create the new CSS and images for you.
-
Chaz over 6 yearsI found this to be browser dependent. Works in Chrome, but not Firefox or IE11.
-
Vucko over 6 years@Chaz check the Browser compatibility.
-
Chaz over 6 years@Vucko, I believe the compatibility issue is with regard to using the content attribute on something that is not :before or :after. From the Browser Compatibility link: The content CSS property is used with the ::before and ::after pseudo-elements to generate content in an element. Try the JSFiddle above in Firefox or IE; it does not work.
-
CliffVandyck over 6 yearsIs there a way to smoothly transition the img?
-
kurdtpage over 6 years@thedigitalmouse good point, I have updated my answer and removed CSS
-
kurdtpage over 6 years@CliffVandyck you could possibly use jQuery animation to do that
-
Nishanth Shaan over 4 yearsSomeone has downvoted my answer. please explain why you downoted for me to unerstand and improve the answer.
-
1.21 gigawatts almost 4 yearsIt's odd that there isn't a CSS src or srcset property yet. Setting the background image is not the same as setting the source. Maybe a candidate for review.
-
Akhilesh Mishra almost 4 yearsYou should add some more details about your answer
-
Hsinhsin Hung about 3 yearsIt's the best answer. Thank you very much.
-
WinEunuuchs2Unix about 2 yearsThis is really cool. Would you answer a new question on click image instead of hover with ability to get current state of on/off? (Top half/bottom half of image currently displayed)? Or would that be a duplicate question?