使用CSS/HTML在悬停时更改图像

84

我遇到了一个问题,当鼠标悬停时,我已经设置了一张图片来显示另一张图片,但是第一张图片仍然出现,新的图片没有改变高度和宽度,重叠在另一张图片上。 我对HTML/CSS还是很新手,可能错过了一些简单的东西。 这是代码:

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

#Library:hover {
    background-image: url('LibraryHoverTrans.png');
    height: 70px;
    width: 120px;
}
22个回答

117

另一个选择是使用 JS:

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

6
尽管这种方法已经被重新使用,但将样式与HTML嵌入在一起实际上是一种不好的做法。所有样式信息都应该包含在HTML文件的顶部,用样式标签嵌入,或者从外部样式表链接。 - the digitalmouse
有没有一种平稳过渡 img 的方式? - CliffVandyck
@thedigitalmouse 说得好,我已经更新了我的答案并删除了CSS。 - kurdtpage
@CliffVandyck 你可以使用jQuery动画来实现这个。 - kurdtpage
非常感谢@kurdtpage提供如此好的解决方案! :) 如果我想在.js文件中执行该代码,它会是什么样子?当我悬停在组件上时,我想在.js文件中运行该代码 :) - Noah

96

一个解决方案是像这样将第一张图片也作为背景图片使用:

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

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

如果您的悬停图像具有不同的尺寸,您需要这样设置它们:

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

谢谢,这个操作也会改变鼠标悬停时新图像的高度和宽度吗? - user2704743
我按照您的解决方案进行了尝试,但出于某种原因大小并没有发生改变,不过hover效果可以正常显示。 - user2704743
是的,我看到了更新,所以我将我的img标签改为div,然后复制了你这里的内容。它修复了悬停,但第一张图片或悬停图片都没有改变大小,我不确定为什么? - user2704743
不,我的意思是“如果您的覆盖图像具有不同的大小,则必须这样设置:”部分... - Aurelio De Rosa
我的图片在链接标签内,这会对任何东西产生影响吗? - user2704743
显示剩余2条评论

51

通常我所做的是创建一个双重图像,包含两种状态,就像两帧电影一样,然后将其用作原始元素的背景,使该元素的宽度/高度以像素为单位设置,从而仅显示图像的一半。然后,悬停状态基本上定义为“移动电影以显示另一帧”。

例如,假设图像必须是灰色Tux,我们需要在悬停时更改为彩色Tux。托管元素是具有id“tuxie”的span元素。

  1. 我创建了一个50 x 25的图像,其中包含两个Tux,一个是彩色的,另一个是灰色的,
  2. 然后将该图像分配为25 x 25的span元素的背景,
  3. 最后将悬停状态简单地设置为向左移动背景25px。

最小化代码:

<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" />

并且这是图片:

Two-frame Tuxie "film"

优点如下:

  • 将两帧放入一个文件中,确保它们同时加载。这避免了在连接速度较慢时出现的不美观的故障,当其他帧无法立即加载时,第一次悬停效果不好。

  • 使用这种方式可能更容易管理您的图像,因为“成对”的帧永远不会混淆。

  • 通过智能使用JavaScript或CSS选择器,可以扩展此功能,并在一个文件中包含更多帧。

    理论上,甚至可以将多个按钮放入单个文件中,并通过坐标来控制它们的显示,尽管这种方法可能很快失控。

请注意,这是使用background CSS属性构建的,因此如果您确实需要与<img />一起使用,您必须设置src属性,因为那会覆盖背景。(想想,在这里巧妙地使用透明度可能会导致有趣的结果,但很可能非常依赖于图像的质量以及引擎的质量。)


2
使用“sprites”可以让网页加载更快。一个很好的在线工具,可以帮助为现有网站创建sprites,它就是SpriteMe。它非常有用,因为它可以为您创建新的CSS和图像,从而更快地创建sprites。 - jagb
这真的很酷。您能否回答一个新问题,即在单击图像而不是悬停时获取当前开/关状态(当前显示的图像的上半部分/下半部分)?还是那将是一个重复的问题? - WinEunuuchs2Unix

42
使用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


4
我认为这是最佳方案。它更简单,使用适当的<img>标签,并且无需担心背景重复等问题。 - Lombas
2
我发现这取决于浏览器。在Chrome中可以工作,但在Firefox或IE11中不行。 - Chaz
@Chaz 请查看浏览器兼容性 - Vucko
1
@Vucko,我认为兼容性问题是关于在不是:before或:after的东西上使用content属性。从浏览器兼容性链接中可以看到:content CSS属性与::before和::after伪元素一起用于在元素中生成内容。请在Firefox或IE中尝试上面的JSFiddle;它无法工作。 - Chaz
1
这是最好的答案。非常感谢。 - Hsinhsin Hung

9

.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>

尝试改进Rashid的好答案,我添加了一些评论:
这个技巧是在要交换的图像的包装器(这次是“a”标签,但可能是其他标签)上完成的,因此已经放置了“hover_image”类。
优点:
- 在同一个地方保持两个图像的url有助于需要更改它们的情况。 - 似乎也可以在旧式导航器中使用(CSS2标准)。 - 它是自解释的。 - 悬停图像已经预加载(悬停后没有延迟)。

6

之前提供的所有答案的问题在于悬停图片并没有随页面一起加载,所以当浏览器调用它时需要时间来加载,整个效果并不是很好。

我所做的是将原始图片和悬停图片放在一个元素中,并在开始时隐藏悬停图片。然后在鼠标悬停时显示悬停图片并隐藏旧的图片,在鼠标移开时反过来。

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");
    }
}

这对我来说是最简单和最有效的方法。

3

您可以更换HTML IMG的图像,而无需对容器div进行任何背景图像更改。

这是使用CSS属性box-sizing: border-box;获得的(它使您能够在<IMG>上非常有效地放置一种悬停效果。)

要做到这一点,请将此类应用于您的图像:

.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;
}

示例代码:http://codepen.io/chriscoyier/pen/cJEjs

原始文章:http://css-tricks.com/replace-the-image-in-an-img-with-css/

希望这能帮助那些不想使用 div 来获得“悬停”效果的人们。

在此发布示例代码:

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");
});

有人给我的回答点了踩,请解释一下为什么你要点踩,让我能够理解并改进我的回答。 - Nishanth Shaan

3

.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>


3
请提供需要翻译的原文,我会尽力进行翻译。 - piyushj
我认为这个方案是最好的,比这里所有潜在的解决方案都要好。 - cusman

2

你不能使用CSS更改图像SRC属性(除非浏览器支持)。 你可能需要使用jQuery和hover事件。

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

1
尝试其中之一。
<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';" />

如果您在表单中使用图像作为按钮,则可以这样做。
<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";
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接