8

What is the appropriate "formula" for a foreground color based on a background color (where the background color may be any color)?

More info:

I want to have my application select a foreground color based on a (solid even) background color. I was thinking along the lines of: black if the total of the RGB components is over (255x3)/2 , and white otherwise. But would rather get the opinion of the experts. Is there an accepted way to do this? Or what would you suggest?

There is a similar question but the answers basically offer to limit the available background colors. That's not an option in this case.

7
  • 2
    I'm voting to close this question as off-topic because it does not appear to be about graphic design, but rather programming.
    – Scott
    Oct 25, 2015 at 19:16
  • @Scott It's about graphic design - What is the appropriate foreground color based on a background color. That's it. The RGB stuff is just to put some context around it that might be helpful for a possible answerer. I'm not asking for any help doing the programming, that's my job. (And is trivial in this case.)
    – ispiro
    Oct 25, 2015 at 19:21
  • @Scott I have edited the question now to make that clearer.
    – ispiro
    Oct 25, 2015 at 19:25
  • Still seems to be about programming an application to me.. but I'm only 1 vote.. so just see what other users think. If anything, it's a possible duplicate of this: graphicdesign.stackexchange.com/questions/19/… or this: graphicdesign.stackexchange.com/questions/9094/…
    – Scott
    Oct 25, 2015 at 19:29
  • 1
    Not sure if I understand the question but if this can help you somehow, maybe you could find clues in the Google dev color specification for apps (I believe). That guide already contains bulletproof instructions for background vs other elements of your interface, and usually very good contrast. In general, using a 20-30% with a 100% offers good contrast and readability (50% isn't enough for contrast). For printing, it's better to stick to 10% for background elements with 100% text on top. google.com/design/spec/style/color.html I hope I make sense.
    – go-junta
    Oct 25, 2015 at 22:15

2 Answers 2

5

I answered a similar question on Game Development Stack Exchange a while ago, so let me summarize the answers there.

You idea of picking either black or white, depending on which one contrasts better with the background color, is sound. However, simply averaging the RGB components will not give a good indication of how light a particular color will appear to the human eye, for (mostly) two reasons:

First of all, for reasons related to human color perception, the red, green and blue channels do not have the same relative luminance; in fact, pure blue (#0000ff) is only about 10% as bright (and pure red only about 30% as bright) as pure green (#00ff00). Thus, e.g. black text on pure blue will never have a particularly good contrast.

For example, the images below show examples of black and white text on pure red, green and blue backgrounds (#ff0000, #00ff00 and #0000ff):

Black and white text on pure RGB red Black and white text on pure RGB green Black and white text on pure RGB blue

You can clearly see the differences in contrast, even though all these colors have the same average RGB value.

The other complication is that the RGB color spaces normally used on computer screens (like sRGB) are not linear, but have a display gamma around 2 or so. That means that e.g. the RGB color #7f7f7f = "50% gray" does not actually appear half as bright as pure white (#ffffff), but rather only about 25% as bright, whereas the color that actually has a relative luminosity halfway between black and white is actually closer to "75% gray" (#bfbfbf).

Conveniently, though, the human eye is also non-linear, and is more sensitive to differences in darker shades. In fact, for shades of gray, the non-linearities roughly cancel out, so that the RGB 50% gray (#7f7f7f) is still perceptually about equally far from both black and white. As a demonstration, here is some black and white text on 25%, 50% and 75% gray backgrounds (#3f3f3f, #7f7f7f and #bfbfbf):

Black and white text on 25% gray Black and white text on 50% gray Black and white text on 75% gray

However, to accurate calculate the luminosity of an arbitrary RGB color, we do need to account for the display gamma, since it's the linear luminosity values that need to be averaged.

To put it all together, to determine whether black or white text would have better contrast on a background, you need to:

  1. convert the gamma-compressed RGB color values into linear RGB,
  2. take a weighted average of the linear R, G and B components, and
  3. compare the resulting average against a suitable threshold.

The threshold value that gives best results may be determined experimentally, but one would generally expect it to lie close to the luminance of 50% RGB gray. In any case, it's worth noting that the perceived contrast will vary depending on the viewer's display settings and viewing conditions, so there is no single optimal value for everybody, but rather a fairly broad range of more or less equally good choices.

If you just want a simple formula to plug numbers into, try this:

  • if 0.2126 × Rγ + 0.7152 × Gγ + 0.0722 × Bγ > 0.5γ, choose black; else choose white,

where γ is the approximate display gamma value (γ = 2.2 is typical).

For an even simpler approximation, you can ignore the gamma correction (i.e. effectively assume that γ = 1) and just use the condition 0.2126 × R + 0.7152 × G + 0.0722 × B > 0.5. For shades of gray, this will make no difference (since we're applying the same gamma to both sides of the inequality), but it does somewhat overestimate the luminance of saturated colors. Fortunately, on such colors, both black and white tend to have decent contrast anyway, so the error may not matter much in practice.

Finally, note that, if the background color is not uniform, it's possible that no single text color may look good. In such cases, you may consider e.g. using black text with a white outline, or vice versa, or perhaps surrounding your text with a semitransparent box of the opposite color.

0

Every colour has three variables; hue, saturation, and brightness.

Key to legibility is contrast which is can be optimised for each of the three variables independent of each other.

For example; the hue contrast can be optimised by finding its complement. The saturation contrast can be optimised by choosing opposites for each ground. Similarly, bright can be contrasted by dim.

This (above criteria) is in regard to only one formula for selection--Optimal Legibility.

There may be other considerations; aesthetic, perceptual, technical, etc.

One practical means of providing this capability has been to use a pre-determined, predictable, and acceptable result by using a Colour Look-Up Table that provides a set given one of the two. For example; given foreground of X, a background of Y is provided. Given a foreground of Y, a background of X is provided. The CLUT can be as complex or as comprehensive as desired for the particular application.

Once the values are known, their selection can be automated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.