23

I am setting the background of a textbox to some variable color.

I know the hex/rgb of the color I'm setting the background to.

Normally the text is black (or very very dark gray).

On some colors, it would be far easier to read the text if it were white instead of black.

How can it be programmatically decided, given a hex/rgb color, whether white or black text would be more readable if placed on top of it?

24

This is standardised by W3C's Web Content Accessibility Guidelines (WCAG) and decided based on the contrast ratio between colors, which you can calculate programmatically.

In your case, you would want to use whichever of white or black has a higher contrast ratio with the background color.

Here is just one of many articles on how to calculate contrast ratio in JavaScript: dev.to: Building your own color contrast checker.

From that article:

The contrast ratio between two colors is calculated using a mathematical function that we will see below. The resulting value of that calculation will go from 1 to 21 (normally represented as 1:1 or 21:1 respectively). If both are the exact same color, the contrast ratio will be 1; The highest contrast is between white and black, and exact opposites in the color wheel (complementary colors) will have high values too.

The mathematical formula is documented by WCAG.

contrast ratio
(L1 + 0.05) / (L2 + 0.05), where

  • L1 is the relative luminance of the lighter of the colors, and
  • L2 is the relative luminance of the darker of the colors.

It uses relative luminance:

For the sRGB colorspace, the relative luminance of a color is defined as L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as:

  • if RsRGB <= 0.03928 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4
  • if GsRGB <= 0.03928 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4
  • if BsRGB <= 0.03928 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4

and RsRGB, GsRGB, and BsRGB are defined as:

  • RsRGB = R8bit/255
  • GsRGB = G8bit/255
  • BsRGB = B8bit/255

There exist free online contrast calculators like this one from WebAIM. In your case, add #fff as one value and your other color as the other. In most cases, you only need WCAG AA passing to be considered accessible. WCAG AA considers a 4.5:1 ratio to be passing. Usually it's good to go just a little darker than a minimum passing value, and the contrast checker can help you find a value for that.

1
  • 11
    4.5:1 is passing, but 7:1 is the recommendation for main body text (for example, the text of the answers here on SE), and speaking from experience as someone who actually has vision issues affected by this, ‘passing’ should not be considered ‘good enough’ unless you are dealing with large font sizes or exceptionally good fonts. Sep 14 at 11:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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