Colour maths: effect of transparent black overlay

2019-09-01 09:06发布

问题:

I've been playing with SASS recently, and have found the darken function, which works by reducing the HSL "lightness" component of a colour by a given amount, to be quite useful. At one point I ended up trying to convert from a semi-transparent black overlay to an equivalent darken application in the following context:

  • Container background: $color (any colour)
    • Content background: darken($color, 20%) (20% darker)
      • Heading background: rgba(0, 0, 0, 0.2) (20% opacity black overlay)

I had thought I could replace the heading background with darken($color, 36%) (80% lightness × 80% lightness = 64% lightness), however that is much darker. The value that produces visually similar results is around 25%.

Obviously 100% opacity equates to 0% lightness, and 0% opacity equates to 100% lightness, but between there the scale seems to be linear for transparency and... not for lightness (due to darken basically subtracting from the lightness component).

So, my question is how can a translucent black overlay be converted to an equivalent reduction in lightness? Is it even possible?

Here's a fiddle with an example of what I mean: http://jsfiddle.net/R7aYP/2 - I'm interested in finding a formula to work out .box.three's darkness percentage from .box.two's opacity.

Edit:

@cimmanon mentioned that the mix function can be used to create the same effect with mix($color, black, 80%) - I'm still interested to know if there's a relationship between this mixing and darken/lighten.

Edit:

I realised this is actually pretty trivial, the darken function simply subtracts the absolute value, e.g.:

darken(blue, 20%) = hsl(hue(blue), saturation(blue), lightness(blue) - 20)

Whereas a mix with black is a percentage reduction, so:

mix(blue, black, 80%) = darken(blue, lightness(blue) * 0.2)

And an obligatory fiddle: http://jsfiddle.net/R7aYP/4/

回答1:

The function you want to use instead is mix(). Since your black is 80% transparent (20% opaque), you'll need to adjust the weight of the mixture in favor of the first color.

.foo {
    background: mix(blue, black, 80%);
}


标签: css colors sass