Say I have a background color with a \"ribbon\" running over it in another solid color. Now, I want the ribbon to be partially transparent to let some details blend through,
Thanks to Phrogz's and ephemer's great answers, here is a SASS function that automagically computes the best equivalent RGBA color.
You call it with the desired color and the existing background, and it will compute the best (meaning most transparent) equivalent RGBA color that gives the desired result within ±1/256 of each RGB component (due to rounding errors):
@function alphaize($desired-color, $background-color) {
$r1: red($background-color);
$g1: green($background-color);
$b1: blue($background-color);
$r2: red($desired-color);
$g2: green($desired-color);
$b2: blue($desired-color);
$alpha: 0;
$r: -1;
$g: -1;
$b: -1;
@while $alpha < 1 and ($r < 0 or $g < 0 or $b < 0
or $r > 255 or $g > 255 or $b > 255) {
$alpha: $alpha + 1/256;
$inv: 1 / $alpha;
$r: $r2 * $inv + $r1 * (1 - $inv);
$g: $g2 * $inv + $g1 * (1 - $inv);
$b: $b2 * $inv + $b1 * (1 - $inv);
}
@return rgba($r, $g, $b, $alpha);
}
I just tested it against a number of combinations (all the Bootswatch themes) and it works a treat, both for dark-on-light and light-on-dark results.
PS: If you need better than ±1/256 precision in the resulting color, you will need to know what kind of rounding algorithm browsers apply when blending rgba colors (I don't know if that is standardized or not) and add a suitable condition to the existing @while, so that it keeps increasing $alpha until it achieves the desired precision.