Why does the final color of two stacked semi-translucent boxes depend on the order?
How could I make it so that I get the same color in both cases?
You are mixing three colors in the following order:
rgba(0, 0, 255, 0.5) over (rgba(255, 0, 0, 0.5) over rgba(255, 255, 255, 1))rgba(255, 0, 0, 0.5) over (rgba(0, 0, 255, 0.5) over rgba(255, 255, 255, 1))And you get different results. This is because the foreground color is blended with background color using normal blend mode1,2 which is not commutative3. And since it is not commutative, swapping foreground and background colors will produce different result.
1 Blending mode is a function that accepts a foreground and background color, applies some formula and returns the resulting color.
2 Given two colors, background and foreground, normal blend mode simply returns the foreground color.
3 An operation is commutative if changing the order of the operands does not change the result e.g. addition is commutative (1 + 2 = 2 + 1) and subtraction is not (1 - 2 ≠ 2 - 1).
The solution is to use a blending mode that is commutative: one that returns same color for same pair of colors in any order (for example the multiply blend mode, which multiplies both colors and returns the resulting color; or darken blend mode, which returns the darker color of the two).
$(function() {
$("#mode").on("change", function() {
var mode = $(this).val();
$("#demo").find(".a, .b").css({
"mix-blend-mode": mode
});
});
});
#demo > div {
width: 12em;
height: 5em;
margin: 1em 0;
}
#demo > div > div {
width: 12em;
height: 4em;
position: relative;
top: .5em;
left: 4em;
}
.a {
background-color: rgba(255, 0, 0, 0.5);
}
.b {
background-color: rgba(0, 0, 255, 0.5);
}
For completeness, here is the formula to calculate composited color:
αs x (1 - αb) x Cs + αs x αb x B(Cb, Cs) + (1 - αs) x αb x Cb
with:
Cs: the color value of the foreground color
αs: the alpha value of the foreground color
Cb: the color value of the background color
αb: the alpha value of the background color
B: the blending function