【问题标题】:css: avoid image hover first time blinkingcss:避免图像悬停第一次闪烁
【发布时间】:2012-10-28 12:20:07
【问题描述】:

我有一个锚点,当悬停在包含background-image 的类class-btn 时,它会更改其背景图像。

悬停时有

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

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

我尝试在 Stack Overflow 上搜索类似的问题,但没有成功。

刚刚添加:

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

所有浏览器都会出现这种情况,因此该解决方案应该适用于所有浏览器。

【问题讨论】:

    标签: html css image hover


    【解决方案1】:

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

    body:after {
     display: none;
     content: url('path/to/image-hovered.jpg') url('path/to/another-image-hovered.jpg');
    }
    

    【讨论】:

    • 起初这对我不起作用,但我现在意识到由于某种原因,您应用这些样式的元素必须是 body:after!
    • @Aaron Franke 这对我适用于任何元素:之后
    • 看起来这不再起作用了。我的猜测是浏览器优化页面加载的方式是不加载隐藏元素的背景。在最近的 Firefox、Safari 和 Chrome 版本中尝试过,当 display: none; 在声明中时,似乎没有一个加载图像。当我尝试使用width: 0; height: 0 时,结果相同。如果它是可见的,它就可以工作,但是会在页面中添加不需要的图像。还有其他人面临同样的情况吗?
    • @Grapestain 跟我一样。有显示时不工作:无;
    • 这个解决方案似乎适用于现代浏览器stackoverflow.com/a/14390213/1108467
    【解决方案2】:

    避免这种情况的最简单方法是使用图像精灵。如需全面了解,请查看this CSS Tricks article

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

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

    具体情况取决于您的图片。您也可以使用在线sprite generator 来简化流程。

    【讨论】:

    • 不错的解决方案。谢谢你的回答。
    • 如果我使用background-size: contain 会怎样?有什么想法吗?
    • 如果您想使用transition 在图像之间淡入淡出,这会起作用吗?我认为不是..
    • 如果 CSS 已经准备好,我不会将其称为修复闪烁的最简单解决方案。但这仍然是一个好方法。
    【解决方案3】:

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

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

    【讨论】:

    • 如果我正在开发浏览器 ID,只加载有效的背景(所以最后一个)以最小化网络负载。我想你可以预料到这迟早不会在任何浏览器中工作。
    • 这在最近的 chrome 更新之前运行良好,现在它已被浏览器优化(这很棒,但会破坏预加载)
    【解决方案4】:

    如果你这样做:

    #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

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

    【讨论】:

    • 有点老套,但它确实有效。我会添加位置:绝对;或更好的显示:无;而不是可见性:隐藏;如果你不想弄乱你的布局。
    • 如果你真的想用伪元素做某事,那就不行了
    【解决方案5】:

    @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 不会加载隐藏图像,或者可能与渲染有关(?)。

    【讨论】:

    • 好收获!谢谢分享!
    • 不错!我建议使用position:absolute; width:0; height:0; overflow:hidden; z-index:-1;。不知何故 left: -50000px 吓坏了我)基本上,问题与此处描述的相同:stackoverflow.com/a/14390213/4810382
    【解决方案6】:

    您可以预加载图片

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

    【讨论】:

      【解决方案7】:

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

      <img src='...' style='display: none' />
      

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

          【解决方案9】:

          “将原始背景图像加倍”技巧对我不起作用,所以我使用了另一个 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;
          }
          

          【讨论】:

            【解决方案10】:

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

            使用两个图像在容器上创建 :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; }
            }
            

            【讨论】:

              【解决方案11】:

              我有同样的问题。 在尝试了与 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);
              

              【讨论】:

                【解决方案12】:

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

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

                【讨论】:

                • OP 想要一个不同的图像作为默认状态和悬停,所以这不起作用
                【解决方案13】:

                执行此操作的最佳方法是将图像插入网页并将显示设置为无。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-01-31
                  • 1970-01-01
                  • 2012-02-29
                  • 1970-01-01
                  • 2014-01-07
                  • 1970-01-01
                  • 2013-07-24
                  相关资源
                  最近更新 更多