70

我有一个锚点,当悬停在一个class-btn包含background-image.

悬停时,它有

a.class-btn:hover
{
    background-image('path/to/image-hovered.jpg');
}

当页面第一次加载并且您第一次悬停此按钮时,它会闪烁(下载悬停的图像大约需要半秒钟)。如何在没有 JavaScript 的情况下避免闪烁(只允许简单的 css 和 html)?

我试图在 Stack Overflow 上搜索类似的问题,但没有运气。

刚刚添加:

  • 我应该“预加载”悬停的图像吗?如何?
  • 我应该使用 z-index 还是 opacity?

它发生在所有浏览器上,因此该解决方案应该适用于所有浏览器。

4

13 回答 13

94

这是我用过几次的简单有效的css图像预加载技术。您可以通过放置内容来加载多个图像: url() url() url()... 等。

body:after {
 display: none;
 content: url('path/to/image-hovered.jpg') url('path/to/another-image-hovered.jpg');
}
于 2015-07-06T08:11:26.460 回答
62

避免这种情况的最简单方法是使用图像精灵。要获得良好的概述,请查看这篇 CSS 技巧文章

这样,您不仅可以解决您看到的闪烁问题,还可以减少 HTTP 请求的数量。您的 CSS 将类似于:

a.class-btn { background: url('path/to/image.jpg') 0 0 no-repeat; }
a.class-btn:hover { background-position: 0 -40px; }

具体情况取决于您的图像。您还可以使用在线精灵生成器来简化该过程。

于 2012-11-08T10:06:33.533 回答
15

我使用的一个简单技巧是将原始背景图像加倍,确保将悬停的图像放在首位

.next {
  background: url(../images/next-hover.png) center center no-repeat;
  background: url(../images/next.png) center center no-repeat;
    &:hover{
      background: url(../images/next-hover.png) center center no-repeat;
    }
 }

没有性能影响,非常简单

或者,如果您还没有使用 SCSS:

.next {
  background: url(../images/next-hover.png) center center no-repeat;
  background: url(../images/next.png) center center no-repeat;        
 }
 .next:hover{
  background: url(../images/next-hover.png) center center no-repeat;
 }
于 2014-03-20T12:30:48.750 回答
8

如果你这样做:

#the-button {
background-image: url('images/img.gif');
}
#the-button:before {
  content: url('images/animated-img.gif');
  width:0;
  height:0;
  visibility:hidden;
}

#the-button:hover {
  background-image: url('images/animated-img.gif');
}

这真的很有帮助!

看这里:

http://particle-in-a-box.com/blog-post/pre-load-hover-images-css-only

PS - 不是我的工作,而是我找到的解决方案:)

于 2015-09-24T08:34:13.133 回答
3

@Kristian 在正文后应用隐藏的“内容:url()”的方法似乎在 Firefox 48.0 (OS X) 中不起作用。

但是,更改“显示:无;” 类似于:

body:after {
 position: absolute; overflow: hidden; left: -50000px;
 content: url(/path/to/picture-1.jpg) url(/path/to/picture-2.jpg);
}

...为我做了诀窍。也许 Firefox 不会加载隐藏图像,或者它可能与渲染有关(?)。

于 2016-08-26T07:55:00.310 回答
2

您可以预加载图像

function preloadImages(srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
    img = new Image();
    img.onload = function() {
        --remaining;
        if (remaining <= 0) {
            callback();
        }
    };
    img.src = srcs[i];
    imgs.push(img);
}
}
// then to call it, you would use this
var imageSrcs = ["src1", "src2", "src3", "src4"];
var images = [];
preloadImages(imageSrcs, images, myFunction);
于 2012-11-08T10:07:54.050 回答
2

这是一个非 CSS 解决方案:如果悬停图像位于一个目录中并且具有通用命名约定,例如包含子字符串 '-on.',则可以选择文件名并将其作为 HTML系列:

<img src='...' style='display: none' />
于 2016-04-29T11:36:00.037 回答
0

“将原始背景图像加倍”技巧对我不起作用,所以我使用了另一个 css 技巧:

.next {
    background: url(../images/next.png) center center no-repeat;        
}
.next:hover {
    background: url(../images/next-hover.png) center center no-repeat;
}
.next:after {
    content: url(../images/next-hover.png);
    display: none;
}
于 2015-02-11T14:53:12.303 回答
0

如果它们的尺寸相同,一种可能性是直接在彼此的顶部绘制两个图像,:hover顶部图像的 CSS 类具有display: none;

这样,两个图像都将被预加载,但悬停将使第二个可见。

于 2012-11-08T10:07:48.687 回答
0

我遇到过同样的问题。在尝试了与 css 相关的所有内容后,我无法解决问题。最终解决问题的是模拟有人悬停该元素。css是正常的。

CSS

#elemName{
 /* ... */
} 
#elemName:hover{
 /* change bg image */
}

JS

var element = document.getElementById('elemName');
var event = new MouseEvent('mouseover', {
  'view': window,
  'bubbles': true,
  'cancelable': true
});
element.dispatchEvent(event);
于 2021-01-24T21:12:30.417 回答
0

这种技术对我来说效果很好,不仅可以确保预加载悬停图像,而且还可以准备好等待显示。(大多数其他解决方案依赖于在悬停时切换背景图像,这似乎需要浏览器一点时间来弄清楚,无论图像预加载多少。)

使用两个图像在容器上创建 :before 和 :after 伪元素,但隐藏您希望在悬停时看到的那个。然后,在悬停时,切换可见性。

只要它们共享相同的大小和定位规则,您应该会看到一个整齐的交换。

.image-container {
    &:before { display: block; background-image: url(uncovered.png); }
    &:after { display: none; background-image: url(uncovered.png); }
}
.image-container:hover {
    &:before { display: none; }
    &:after { display: block; }
}
于 2019-08-22T15:56:24.070 回答
-2

只需更改背景图像的大小,而不是它的来源!所以...

a.class-btn {
    background-image: url('path/to/image-hovered.jpg');
    background-size: 0;
}
a.class-btn:hover {
    background-size: auto;
}
于 2012-11-08T10:09:04.447 回答
-3

最好的方法是将图像插入网页并将显示设置为无。

于 2013-08-17T05:26:33.743 回答