Overlay a background-image with an rgba color, with a CSS3 transition

69,382

Solution 1

Yes, it is possible.

demo

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

What am I doing here?

What I am doing here is that I am setting a RGBa background-color on the div, behind its background-image and transitioning this background-color (its alpha) on :hover. All this happens behind the background-image. However, I am also using background-color: inherit on the pseudo-element, which means that, at any given moment, the pseudo-element, which is situated above its parent div (and therefore above the background-image of the div) is going to have the same background-color (meaning that the background-color of the pseudo-element is going to transition from rgba(0,0,0,0) to rgba(0,0,0,.5) on :hover).


Why do it this way?

The reason why I am not transitioning directly the background-color of the pseudo-element is that support for transitions on pseudo-elements is still not that good yet.

Support for transitions on pseudo-elements

✓ Firefox supports transitions on pseudo-elements and has supported them for quite a while, let's get this out of the way first.

Current versions of Safari and Opera don't support transitions on pseudo-elements.

Chrome supports transitions on pseudo-elements only starting from version 26.

IE10 supports them in a bit of a weird way, meaning that something like:

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

won't work, you have to specify the hover state on the element itself as well. Like this:

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

More info and examples about how you can transition various properties of pseudo-elements using this inherit technique: http://vimeo.com/51897358


EDIT

Transitions directly on pseudo-elements are now supported in Opera since the switch to Blink and in Safari since 6.1.

Solution 2

Allthough @Ana technique is also nice, and works fine, allow me to slightly alter my answer to the previous question, and add the transition in that code. 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);   
}

What I did is i defined the :after pseudo element on the default state of the div in stead of only on the hover state, but with a fully transparent background, and a transition on the background color. On hover of the div, I change the background color of the pseudo element to be less transparent. Thanks to the transition it fades in nicely.

The technique is basicly the same as what @Ana did, but perhaps a bit more intuitive because I don't use the background-color: inherit;. Also if the div would becomes bigger then the background image, you would not get the 'double darkness' on the edges, as demonstrated here http://codepen.io/anon/pen/cjoHr versus here http://jsfiddle.net/Pevara/N2U6B/3/

Share:
69,382

Related videos on Youtube

Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    Earlier today I asked Overlay a background-image with an rgba background-color. My goal is to have a div with a background-image, and when someone hovers the div, the background-image gets overlayed with an rgba color. In the answer, a solution with :after was given:

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

    I now would like to have the same, but with a CSS transition: I'd like the background color to fade in. I tried adding transition: all 1s; to the #the-div CSS, but that didn't work. I also try to add it to #the-div:hover and #the-div:after, but that didn't work either.

    Is there a pure CSS way to add a fading in overlay to a div with a background-image?

  • Andrey Mikhaylov - lolmaus
    Andrey Mikhaylov - lolmaus almost 11 years
    That's quite an ingenious solution! I suggest specifying the transition property so that the element is not animated on page load: transition: background-color 1s;.
  • Ana
    Ana almost 11 years
    True. Added the transitioned property name.
  • Admin
    Admin almost 11 years
    I'm glad to see that there still are people on SO that provide explanation on their code :) good practice, keep up the good work!
  • Ana
    Ana almost 11 years
    True, this is more straightforward. The only problem is support. It's only going to work in Firefox and Chrome 26+. I've edited my answer to include info about support.
  • Admin
    Admin almost 11 years
    @lolmaus I'll probably do that, but perhaps others have even better answers :)
  • Pevara
    Pevara almost 11 years
    @ana as Chrome user I was not aware of that restriction in most browsers. Some day... Thanks for teaching me something new, and +1 to you!