oceanGermanique
oceanGermanique

Reputation: 409

where to find the formulas used for color calculations in CSS?

My question is about CSS properties source code

for example the opacity property. I wanted to understand how the color is calculated.
The method I'm going to describe gives the same RGB values that I get after taking a screenshot and reading the colors.

Here is the html & css document, the goal is to understand the color it will display.

#div1 {
  opacity: 0.6;
  background-color: rgba( 155 , 66 , 200 , 0.5 );
  width:200px;
  height: 200px;
}

#div2 {
  background-color: rgba( 0, 77 , 100 , 0.8 );
  width: 200px;
  height: 200px;
}
<div id="div1" >
    <div id= "div2"></div>
 </div>

first i calculate the composite color : co

 co = Cs * as + Cb * ab * ( 1 - as)  
 ao = as + ab * ( 1 - as )

Cs and as is the RGB and alpha of div2
Cb and ab is the RGB and alpha of div1

co = ( 0 , 77/255 , 100/255 ) * 0.8 + ( 155/255 , 66/255 , 200/255 ) * 0.5 * ( 1 - 0.8 )  
co = ( 0.06 , 0.267 , 0.392 )  
ao = 0.8 + 0.5 * ( 1 - 0.8 )  
ao = 0.9  

here is the result, it is a premultiplied color : RGBA = ( 0.06 , 0.267 , 0.392 , 0.9)

Now I apply the opacity :

(*) I multiply the result - the premultiplied color - by the value of the opacity

= ( R , G , B , A ) * opacity = ( 0.06 , 0.267 , 0.392 , 0.9) * 0.6 = ( 0.036 , 0.1602 , 0.2352 , 0.54 )

Now, we extract the color component of this pre-multiplied value ,
we divide ( 0.036 , 0.1602 , 0.2352 ) by 0.54 :

( 0.07 , 0.27 , 0.43 )

and we compose the result with the background color (the white color) :

color_screen = ( 0.07 , 0.27 , 0.43 ) * 0.54  + ( 1 , 1 , 1 ) * 1 * ( 1 - 0.54 )  

This result corresponds to the one measured after a screenshot


Finally, here is my question: it concerns step (*),
I applied the opacity on the premultiplied color.
And that's what gives me the final result equal to the screenshot.
In short : If my result matches the theory :

why is the opacity applied to the premultiplied color ?

here are the two possible schemes, and I wonder why
it's the first one that seems to be chosen :

first possibility

1 : blending, compositing

2 : (r,g,b,a) = premultiplied value after compositing
3 : apply opacity on this premultiplied value : ( r * opacity , g * opacity, b * opacity, a * opacity)
4 : EXTRACT the color component :
(r * opacity / (a * opacity) , g * opacity / (a * opacity) , b * opacity / (a * opacity) , a * opacity )
= ( r/a , g/a , b/a , a * opacity)

second possibility

1 : blending, compositing

2 : (r,g,b,a) = premultiplied value after compositing
3 : EXTRACT the color component : (r/a, g/a, b/a , a )
4 : apply opacity on this color : ( r/a * opacity , g/a * opacity, b/a * opacity, a * opacity )

why the first method seems to have been chosen ? or find the sources ?

Upvotes: 1

Views: 180

Answers (2)

oceanGermanique
oceanGermanique

Reputation: 409

OK, I was wrong. Opacity is multiplied by alpha only, not R, G, and B.

second possibility (modified) :
1 : blending, compositing
2 : (r,g,b,a) = premultiplied value after compositing
3 : EXTRACT the color component : (r/a, g/a, b/a , a )
4 : apply opacity on this color : ( r/a , g/a , b/a , a * opacity )

So I find the same result as with my first possibility

the calculation of the first possibility reached the same result as a screenshot...but with a coherent calculation this time!

Upvotes: 0

Temani Afif
Temani Afif

Reputation: 274069

I think your answer is somewhere here: https://drafts.csswg.org/css-color-3/#opacity

Opacity can be thought of as a postprocessing operation. Conceptually, after the element (including its descendants) is rendered into an RGBA offscreen image, the opacity setting specifies how to blend the offscreen rendering into the current composite rendering. See simple alpha compositing for details.

If you follow the links you will probably find more details

Upvotes: 1

Related Questions