【问题标题】:Overlay a background-image with an rgba background-color用 rgba 背景颜色覆盖背景图像
【发布时间】:2013-06-16 15:39:31
【问题描述】:

我有一个div 和一个background-image。当用户悬停 div 时,我想用 rgba 颜色 (rgba(0,0,0,0.1)) 覆盖背景图像。

我想知道是否有一个 div 解决方案(即没有多个 div,一个用于图像,一个用于颜色等)。

我尝试了多种方法:

<div class="the-div" id="test-1"></div>
<div class="the-div" id="test-2"></div>
<div class="the-div" id="test-3"></div>

还有这个 CSS:

.the-div {
    background-image: url('the-image');
    margin: 10px;
    width: 200px;
    height: 80px;
}

#test-1:hover {
    background-color: rgba(0,0,0,0.1);
}

#test-2:hover {
    background: url('the-image'), rgba(0,0,0,0.1);
}

#test-3:hover {
    background: rgba(0,0,0,0.1);
}

this fiddle

我看到的唯一选择是制作另一个带有叠加层的图像,使用 JavaScript 预加载它,然后使用 .the-div:hover { background: url('the-new-image'); }。但是,我想要一个纯 CSS 的解决方案(更整洁;更少的 HTTP 请求;更少的硬盘)。有吗?

【问题讨论】:

    标签: css background background-image rgba


    【解决方案1】:

    PeterVR 的解决方案的缺点是额外的颜色显示在整个 HTML 块的顶部 - 这意味着它也显示在 div 内容的顶部,而不仅仅是背景图像的顶部。如果您的 div 为空,这很好,但如果它不使用线性渐变可能是更好的解决方案:

    <div class="the-div">Red text</div>
    
    <style type="text/css">
      .the-div
      {
        background-image: url("the-image.png");
        color: #f00;
        margin: 10px;
        width: 200px;
        height: 80px;
      }
      .the-div:hover
      {
        background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("the-image.png");
        background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("the-image.png");
        background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("the-image.png");
        background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("the-image.png");
        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.1)), to(rgba(0, 0, 0, 0.1))), url("the-image.png");
        background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), url("the-image.png");
      }
    </style>
    

    fiddle。太糟糕了,梯度规范目前一团糟。请参阅compatibility table,上面的代码应该可以在任何具有显着市场份额的浏览器中运行 - MSIE 9.0 和更早版本除外。

    编辑(2017 年 3 月):网络状态现在变得不那么混乱了。所以linear-gradient(Firefox 和 Internet Explorer 支持)和-webkit-linear-gradient(Chrome、Opera 和 Safari 支持)行就足够了,不再需要额外的前缀版本。

    【讨论】:

    • 您可以通过使用 base64 编码的 1px x 1px 图像以您想要的颜色稍微优化这一点。只需使用编码的 png,您就可以获得透明度和所有内容。 base64 图像的缺点是可读性差,并且不容易快速更改。不过,您确实避免了为所有渐变规范额外增加 5 行。
    • @RedEight:应该不再需要-moz-ms 版本,旧的WebKit 符号也是如此。我猜-o 也不是必需的,较新的 Opera 版本基于 WebKit。所以你真的只需要两行。
    【解决方案2】:

    是的,有办法做到这一点。您可以使用伪元素after 在背景图像顶部放置一个块。像这样的东西: http://jsfiddle.net/Pevara/N2U6B/

    :after 的 css 如下所示:

    #the-div:hover:after {
        content: ' ';
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        background-color: rgba(0,0,0,.5);
    }
    

    编辑:
    当您想将其应用于非空元素并仅在背景上获得叠加层时,您可以通过对元素应用正数z-index 和对:after 应用负数来实现。像这样的:

    #the-div {
        ...
        z-index: 1;
    }
    #the-div:hover:after {
        ...
        z-index: -1;
    }
    

    还有更新的小提琴:http://jsfiddle.net/N2U6B/255/

    【讨论】:

    • 这是一个不错的技巧,但不幸的是,这一层也覆盖了文本,而不仅仅是背景图像。所以这只适用于空的div。
    • @WladimirPalant 如果您添加 z-index,它仍然适用于非空元素。查看更新。
    【解决方案3】:

    /* Working method */
    .tinted-image {
      background: 
        /* top, transparent red, faked with gradient */ 
        linear-gradient(
          rgba(255, 0, 0, 0.45), 
          rgba(255, 0, 0, 0.45)
        ),
        /* bottom, image */
        url(https://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg);
        height: 1280px;
        width: 960px;
        background-size: cover;
    }
    
    .tinted-image p {
        color: #fff;
        padding: 100px;
      }
    <div class="tinted-image">
      
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam distinctio, temporibus tempora a eveniet quas  qui veritatis sunt perferendis harum!</p>
      
    </div>

    来源:https://css-tricks.com/tinted-images-multiple-backgrounds/

    【讨论】:

    • 代码 sn-p 对我不起作用,也没有做 OP 想要的。
    【解决方案4】:

    理想情况下,background 属性将允许我们对各种背景进行分层,类似于http://www.css3.info/preview/multiple-backgrounds/ 中详述的背景图像分层。不幸的是,至少在 Chrome (40.0.2214.115) 中,在 url() 图像背景旁边添加 rgba 背景似乎会破坏该属性。

    我找到的解决方案是将 rgba 层渲染为 1px*1px Base64 编码的图像并内联它。

    .the-div:hover {
      background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgkAQAABwAGkn5GOoAAAAASUVORK5CYII=), url("the-image.png");
    }
    

    对于 base64 编码的 1*1 像素图像,我使用了http://px64.net/

    这是您所做的这些更改的 jsfiddle。 http://jsfiddle.net/325Ft/49/(我还把图片换成了网上还存在的一张)

    【讨论】:

    • 你在这里得到的一个小答案。我今天最终使用了它,因为它也适用于 IE9。谢谢大佬。
    【解决方案5】:

    我已经完成了以下工作:

    html {
      background:
          linear-gradient(rgba(0,184,255,0.45),rgba(0,184,255,0.45)),
          url('bgimage.jpg') no-repeat center center fixed;
      -webkit-background-size: cover;
      -moz-background-size: cover;
      -o-background-size: cover;
      background-size: cover;
    }
    

    上面将产生一个漂亮的不透明蓝色叠加层。

    【讨论】: