# How to find an accessible color by changing lightness only?

Is the following hypothesis true?

For any given color:

``````{ Hue, Saturation, Lightness_1 }
``````

there exists:

``````Lightness_2
``````

such that the contrast ratio between:

``````{ Hue, Saturation, Lightness_1 }
``````

and

``````{ Hue, Saturation, Lightness_2 }
``````

is at least `4.5`.

Bonus question: How could I find such `Lightness_2`?

• In the WCAG definition of ‘contrast ratio’ that you linked to, `L1` and `L2` are used as symbols for relative luminance which is usually indicated by `Y` instead (as in XYZ or xyY), which in turn is easily and often confused with luma `Y’` (as in Y’UV or Y’CrCb). In HSL colors, however, the `L` stands for lightness! L = (max(R,G,B) + min(R,G,B)) / 2 – Crissov Jul 31 '15 at 12:19
• @Crissov Thanks for pointing this out. I updated the question to avoid this confusion. – Misha Moroshko Jul 31 '15 at 12:23
• Cross-post – unor Jul 31 '15 at 17:28

There is no simple formula that links L in HSL with WCAG contrast ratio or relative luminance Y (or what WCAG confusingly calls L). However, there is one for RGB which allows you to use some algebra to find colors that contrast at a certain level with another known color.

Find the Brightness (Relative Luminance) you Need

Contrast ratio, C, is:

C = (Y1 + 0.05) / (Y2 + 0.05)

Where Y1 and Y2 are the relative luminance, Y, of the two colors; Y1 is the lighter color, whether it’s foreground or background. You can get Y from RGB values with:

Y = 0.2126 * (R/255)^2.2 + 0.7151 * (G/255)^2.2 + 0.0721 * (B/255)^2.2

That’s not quite the formula used by WCAG, but it gets pretty close, and makes the algebra much easier. If you “pad” your 4.5 minimum a bit, you’ll be safe in meeting the standard. Let’s use C = 4.6.

So, if you’ve already selected the lighter color, then the answer to your second question (but using Y2, not Lightness_2) is:

Y2 = (Y1 + 0.05) / 4.6 – 0.05

Y2 = [ 0.2126 * (R1/255)^2.2 + 0.7151 * (G1/255)^2.2 + 0.0721 * (B1/255)^2.2 + 0.05 ] / 4.6 – 0.05

Y2 = ( 1.0794e-6 * R1^2.2 + 3.6306e-6 * G2^2.2 + 3.6606e-7 * B2^2.2 + 0.05 ) / 4.6 – 0.05

Where R1, G1, B1 are the RGBs of your known color. If your lighter color is a pale blue (192, 224, 255), then Y1 = 0.7237, and Y2 = 0.1182

Finding a Specific Color

There are many many colors that will equal Y2 (many possible combinations of RGB), and many many more that are equal to or less than Y2. To actually determine a color, set some constraints of the relative proportions of RGB, and continue with the algebra. Select constraints that will get you in the ballpark of the color you’re looking for. You can always fiddle with the RGB (or HSL) values afterward, and check if it still complies with the WCAG standard.

For example, let’s say you want a nice rich shade of brown. Browns have an R to G ratio of about 2:1, or R2 = 2*G2. To keep it rich, we’ll set B2 = 0. Let X = G2, so:

Y2 = 0.2126 * (R2/255)^2.2 + 0.7151 * (G2/255)^2.2 + 0.0721 * (B2/255)^2.2

Y2 = 0.2126 * (2*X/255)^2.2 + 0.7151 * (X/255)^2.2 + 0.0721 * (0/255)^2.2

Y2 = 4.9595e-6 * X^2.2 + 3.6306e-6 * X^2.2

Y2 = 8.5901e-6 * X^2.2

Y2 is 0.1182, so solving for X

X = (0.1182 / 8.5901e-6) ^ 1/2.2 = 76

So your RGB color is 152, 76, 0.