CSS image opacity rollover glitches

Problem

I made this rollover:

jsfiddle.net/DH6Lu/

But as you can see the background image glitches. This is not the case when I don't use the opacity on the main div:

http://jsfiddle.net/6KT9p/

Any idea what is wrong?

<div id="opacity">
    <div class="box">
        <a class="link" href="#">
            <div class="inner">
                <img src="http://lorempixel.com/340/192/" width="340" height="192">
                <div class="description">
                    <h3>titel2</h3>
                </div>
            </div>
        </a>
    </div>
</div>
.box {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}
.inner {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    overflow: hidden;
}
.inner img {
    position: absolute;
    opacity: 1;
    -webkit-transition: opacity  0.5s ease;
}
.inner img:hover {
    opacity: 0.15
}
.description {
    background: url(http://www.merkendiewerken.be/wp-content/themes/merkendiewerken/img/close-recent.png) #aaa repeat 0 0 fixed;
    width: 340px;
    height: 192px;
    position: absolute;
    z-index: -1;
}
.description h3 {
    color: #fff;
    font-size: 18px;
    text-transform: uppercase;
    text-align: center;
    position: absolute;
}
#opacity {
    opacity: 0.5
}
Problem courtesy of: user2987394

Solution

The problem arises from the fixed property of the background. Set the CSS to

.description {
    background: url(http://www.merkendiewerken.be/wp-content/themes/merkendiewerken/img/close-recent.png) #aaa repeat 0 0;
    width: 340px;
    height: 192px;
    position: absolute;
    z-index: -1;
}

and it will work

fiddle

The problem is also linked to the GPU handling this different from the CPU. The GPU is handling the background during the transtion, the CPU in the static states. If you set transform: translateZ(1px) - one of the usual tricks to enable GPU - the background will be permanently in an offset. It solves the glitch, but the look isn't correct.

Solution courtesy of: vals

Discussion

I guess it glitches because .inner inherits the opacity from #opacity... but I don't know why. Interesting.

Still, I have a workaround for your case, if you want to keep the initial alpha to 0.5: make the .inner half visible, hide the .description unless it's hovered.

The adjacent sibling selector + is useful to show the description when the image is hovered.

Here's what you have to add (existent properties omitted):

.inner img {
    -webkit-transition: opacity 0.5s ease;
    opacity:0.5;
}

.inner img:hover{
    opacity:0.15;
}
.inner img:hover + .description{
    opacity:1;
}
.description {
    -webkit-transition: opacity 0.5s ease;
    opacity:0;
}

Here's a working demo for this.

Discussion courtesy of: Bigood

This recipe can be found in it's original form on Stack Over Flow.