Given a background color, what is the best way to determine if I should use black or white for the foreground color?
For example, could I use a formula based on the HSB values of the color?
It's for an app in which the background color is dynamic.
I have used a javscript based color picker on some of my sites, and the font color within the input box changes based on the values the picker chooses...
The code (Direct Code Link Here) for the script shows a specific location for the colorization of the input box the script is attached to.
Within that code you can see the formula:
0.213 * this.rgb[ 0 ] + 0.715 * this.rgb[ 1 ] + 0.072 * this.rgb[ 2 ]
With the result being:
< 0.5 ? '#FFF' : '#000';
or... (IF) less than 0.5 of the pure white (255) = 'White' (Otherwise) = 'Black';
You can extrapolate from that formula that:
0.213 * your RED value (0 - 255) +
0.715 * your Blue Value (0 - 255) +
0.072 * your Green value (0 - 255)
gives you a number
...and if that number is greater than .5,
you should opt for a Black font color, otherwise, go for white.
0.213 * 21 = 4.473
0.715 * 57 = 33.605
0.072 * 117 = 8.424
4.473 + 33.605 + 8.424 = 46.502
Since 46.502 is less than .5 of the pure white (255), we should use white on this background.
Hope this helps.
See this answer to a similar question: See How to calculate the best type colour for a random background colour?
Applying this theory, For you to figure out dynamically, you could use RGB values or hex colors. In hex the color codes go from 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. So #751 or #745814 is 7 or in red, 5 in green and 1 in blue (RGB). Every second number in the 6-digit hex is just "fine tuning".
Midway point makes <=7 is darker than 50%, >=8 is lighter (technically it is more saturated). So you can programmatically find an accumulative score and apply black text to the lighter colors, and vice versa.
I would say if your background color is constantly changing, that indeed going with a neutral color would be best. Depending on how bright or dark the background becomes should determine, whether you use white or black. Pick a middle ground between all of the background colors and scale your colors from darkest to lightest. Then with the darker backgrounds, use white, and as you reach more of the lighter colors you should then switch black. Maybe even throw some of the in between grays in there as well. So all in all setup up to scales, one with your colors from dark to light and then a scale below it with white to black. That way you will know which color is best used. Hope this helps. Also this is really opinion based, so others may or may not agree with me or even give their own thoughts. Good Luck!
Another alternative I found a couple of days ago and made the whole process of finding contrast ratios REALLY easy:
You can copy-past HEX values in the boxes and it automatically gives you a number. If you try with white and black plus the color you should have a result in less than 5 seconds :)