使用CSS3过渡将背景图像覆盖一个RGBA颜色。

19
早些时候,我在Overlay a background-image with an rgba background-color上发了一个问题。我的目标是有一个带有背景图像的div,当有人将鼠标悬停在div上时,背景图像会叠加上rgba颜色。在答案中,提供了一个使用:after的解决方案:
#the-div {
    background-image: url('some-url');
}

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

我现在想要同样的效果,但加上CSS过渡效果:我希望背景颜色能够渐变。我尝试在#the-div的CSS中添加transition: all 1s;,但这没有生效。我还尝试将其添加到#the-div:hover#the-div:after,但这些也没有生效。

是否有一种纯CSS的方法为具有background-image的div添加淡入叠加层效果?

2个回答

34

是的,这是可能的。

演示

.boo {
  position: relative;
  width: 20em; min-height: 10em;
  background: rgba(0,0,0,0) url(http://placekitten.com/320/160);
  transition: background-color 1s;
}
.boo:hover {
  background-color: rgba(0,0,0,.5);
}
.boo:before {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background-color: inherit;
  content: ' ';
}

我在这里做什么?

我在这里的目的是在 div 元素的 background-image 后面设置一个 RGBa background-color,并将此 background-color (alpha 值)在 :hover 时进行过渡。所有这些都发生在 background-image 的“后面”。但是,我还在伪元素上使用了 background-color: inherit,这意味着在任何给定时刻,位于其父元素 div 上方(因此在 divbackground-image 上方)的伪元素将具有相同的 background-color(这意味着伪元素的 background-color 将从 rgba(0,0,0,0) 过渡到 rgba(0,0,0,.5))。


为什么要这样做?

我之所以不直接过渡伪元素的 background-color,是因为对于伪元素的过渡支持仍然不太好。

伪元素过渡的支持情况

✓ Firefox 支持伪元素过渡,并且已经支持了相当长一段时间,我们先把这个说清楚。

当前版本的 SafariOpera 不支持伪元素过渡。

Chrome 仅从版本 26 开始支持伪元素过渡。

IE10 支持它们的方式有点奇怪,这意味着像:

.boo:before { color: blue; transition: 1s; }
.boo:hover:before { color: red; }

这样不起作用,你还需要在元素本身上指定悬停状态。像这样:

.boo:hover {}
.boo:before { color: blue; transition: 1s; }
.boo:hover:before { color: red; }

了解更多关于如何使用 inherit 技巧来转换伪元素的各种属性的信息和示例:http://vimeo.com/51897358


编辑

自从转换到 Blink 引擎以来,Opera 和 Safari 6.1 以上版本现在都支持直接在伪元素上进行过渡。


2
这是一个非常巧妙的解决方案!我建议指定过渡属性,以便在页面加载时不对元素进行动画处理:transition: background-color 1s; - Andrey Mikhaylov - lolmaus
已经完成了翻译,以下是翻译后的文本: True。添加了转换后的属性名称。 - Ana
2
很高兴看到在SO上仍有人提供他们代码的解释 :) 这是一个好习惯,继续保持! - user1544337
@lolmaus 我可能会这样做,但也许其他人有更好的答案 :) - user1544337

5
虽然@Ana的技术也很好,并且有效,但请允许我稍微改变我的答案(上一个问题)并在该代码中添加转换。 http://jsfiddle.net/Pevara/N2U6B/2/
#the-div {
    width: 500px;
    height: 500px;
    background: url(http://placekitten.com/500/500) no-repeat center center;
    position: relative;
}

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

我所做的是在div的默认状态下定义了:after伪元素,而不仅仅是在悬停状态下,并且背景完全透明,并在背景颜色上进行过渡。在悬停div时,我将伪元素的背景颜色改变为更少透明。由于过渡效果,它会很好地淡入。
这种技术基本上与@Ana所做的相同,但可能更直观,因为我不使用background-color: inherit;。此外,如果div变得比背景图像更大,则不会在边缘处获得“双重黑暗”,如此演示http://codepen.io/anon/pen/cjoHr与此处http://jsfiddle.net/Pevara/N2U6B/3/

1
是的,这更加直接。唯一的问题是支持。它只能在Firefox和Chrome 26+中使用。我编辑了我的答案以包括有关支持的信息。 - Ana
作为Chrome用户的@ana,我之前并不知道大多数浏览器都有这种限制。感谢你教给我新的东西,给你点赞! - Pevara

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