I had occasion recently to need to find a foreground colour that worked well with a variety of backgrounds. Backgrounds that included black, white, a couple of shades of grey, and a blue like you find with highlighted or selected fields and active buttons.


I started off trying a few colours manually and was using the excellent Colour Contraster Checker at Snook.ca to get the actual contrast ratios. But I felt I needed to know how close my choice was to the optimal colour for the highest contrast ratio against all the possible background colours.

I needed numbers.

Of course there was the qualitative effect too – a colour that happens to have an equal contrast ratio against white and black might still be improved on from a purely visual perspective, since the way pixels appear when surrounded by on-pixels (white) is different to that when surrounded by off-pixels (black). Generally white on black needs to be a little bolder than the inverse. But still – I needed numbers to know where I stood.

I wrote a program (in C++, using Qt) to determine what the optimal colour choice was for the highest contrast ratio. It turned out there’s a red, a green and a blue that worked equally well so I took the blue, although remarkably it was less than a 1% improvement over my manual choice. (It wasn’t possible to get a contrast ratio of more than about 2.13 for all the colours.)

But having got that far, I was then curious about what colour backgrounds white or black foregrounds work best with, purely from the point of view of colour contrast. I adapted the program accordingly to generate the charts below showing the best foreground colour for varying backgrounds in the HSL colour space.

Foreground colours are either off-white (#F0F0F0) or off-black (#101010) depending on which gives the highest contrast ratio against each background. Absolute black/white is generally avoided as they can appear rather harsh on the eye.

Each colour cell has a circle:

  • Solid circles: contrast ratio <= 4.5
  • Thick circles: contrast ratio > 4.5 (WCAG 2.0 AA compliant for 14 pt text)
  • Thin circles: contrast ratio > 7 (WCAG 2.0 AAA compliant for 14pt text)

In the first chart, lightness is a constant 128, while hue and saturation vary:

It’s interesting to see that black is generally much better than white, except in the blues and reds. There were no yellows and greens where white was better and black has a contrast ratio of over 7 for a great swathe of those yellows and greens, while white struggles to get the ratio over 7 except in the purest deep blues. The gap in the purples where black again excels is intriguing too.

In the second chart, saturation is a constant 255, while hue and lightness vary:


Unsurprisingly, white works on black and black works on white, but again black dominates overall except in the blues. Black dominates most against the yellows. There’s not a lot of surprises here, but it’s compelling to see the evidence laid out like this. Unlike the varying saturation, here a vast majority of the ratios get above 7 (the thin circles).

Finally (so far), I felt it might be useful to see what the actual contrast ratio is for any of the colours, so I changed the output to an interactive SVG format with tooltips over each colour cell.

Got ideas for enhancements? Let me know!