14

I've stumbled upon an issue with rendering two overlapping elements with opacity = .5. The elements are exactly the same and positioned absolutely. One is on top of the other. Common sense tells that the effect should give us an image with 100% opacity (0.5+0.5 = 1), but it doesn't.

I would really appreciate if anyone cared to explain the mechanism of rendering such elements, because clearly there's some underlying issue that I don't get.

HTML:

<div class="test">
    <img src="..." alt="" width="200" height="200" class="t"/>
    <img src="..." alt="" width="200" height="200" class="t"/>   
</div>
<img src="..." alt="" width="200" height="200" class="test"/> 

CSS:

.test{
    float: left;
    position:relative;
    width: 200px;
    height: 200px;
}
.test .t{
    position:absolute;
    top:0;
    left:0;
    opacity: 0.5;
}


jsFiddle

Thanks

mpietrowiak
  • 215
  • 2
  • 7
  • Your not just adding the image to the image. There's the white background too. The first image mixes with the white. The second image mixes with the result of the first mix. – TheSavage Jan 22 '14 at 22:54
  • 1
    **It's not** 0.5+0.5 but rather **0.5 * 0.5** which is 75% opaque. Using your thinking how would three elements look like stacked on top of each other with opacity of 0.5? 150% opaque? Well no. They'd be 87.5% opaque combined. – Robert Koritnik Jan 22 '14 at 23:01
  • @TheSavage, the white background has 0 impact on the opacity of the elements. Don't confuse brightness with opacity. – brouxhaha Jan 22 '14 at 23:09

3 Answers3

19

Try and think of it like percentage sales. It's a bit different, but the analogy gives sense of what's happening. When a $10 item is 80% off, then you take off an additional 20%, it's' not 100% off (80% + 20%). You calculate final price like this:

$10 * (1 - 0.8)  = $2 * (1 - 0.2) = $1.60.

50% opacity means, 50% of the light is blocked. So when you stack two 50% opacity elements, that means 50% of the light is blocked and 50% more light is blocked by the additional layer. Since only 50% light is coming through the first layer, only 50% of that additional light is blocked. So the calculation would be:

50% + (50% * 50%) = 75% opacity.

DEMO

.num2 {
    opacity: 0.75;
}
brouxhaha
  • 4,003
  • 1
  • 19
  • 22
  • many thanks for this constructive reply; so you think we can't retrive the 100% opacity with 2 `img` overlapping? – kevpoccs Jan 23 '14 at 08:00
  • Could you explain the `50% + (50% * 50%)` equation? I think I understand the two values in brackets to be the elements which are stacked. Why is it added to 50%? – bozdoz Sep 02 '14 at 22:34
  • 1
    Think of having two windows that each allow 50% of the light to pass through. The first window will block 50% of the light that comes through, which means 50% of the initial light passes to the next window. That window then blocks 50% of that remaining light from the first window, which means 25% (50% of 50% OR 50% * 50% OR 1/2 * 50%) of the initial light is coming through the second window. – brouxhaha Sep 03 '14 at 15:25
2

There are three items being added together:

  • White background at 100%
  • First picture at 50%
  • Second picture at 50%

The first two make the first picture much lighter prior to mixing with the second picture.

Don Rhummy
  • 24,730
  • 42
  • 175
  • 330
  • If you have a black background, you still have two images at 50% opacity resulting in a combined 75% opacity. Lightness and opacity are unrelated. – brouxhaha Jan 22 '14 at 23:08
1

Short answer: Opacity is not a linear function, so it doesn't add.

Longer answer: here or here

Stephen Thomas
  • 13,843
  • 2
  • 32
  • 53