// Contrast ratios can range from 1 to 21 (commonly written 1:1 to 21:1). public static double Contrast(this IColorType thisA, IColorType color) { // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef var alpha = thisA.Alpha0To1; if (alpha >= 1) { if (color.Alpha0To1 < 1) { color = color.OverlayOn(thisA); } var l1 = thisA.Luminance0To1() + .05; var l2 = color.Luminance0To1() + .05; var ratio = l1 / l2; if (l2 > l1) { ratio = 1 / ratio; } ratio = Math.Round(ratio, 1); return(ratio); } // If we’re here, it means we have a semi-transparent background // The text color may or may not be semi-transparent, but that doesn't matter var onBlack = thisA.OverlayOn(Color.Black); var onWhite = thisA.OverlayOn(Color.White); var contrastOnBlack = onBlack.Contrast(color); var contrastOnWhite = onWhite.Contrast(color); var max = Math.Max(contrastOnBlack, contrastOnWhite); var min = 1.0; if (onBlack.Luminance0To1() > color.Luminance0To1()) { min = contrastOnBlack; } else if (onWhite.Luminance0To1() < color.Luminance0To1()) { min = contrastOnWhite; } var error = Math.Round((max - min) / 2, 2); var farthest = contrastOnWhite == max ? Color.White : Color.Black; return(Math.Round((min + max) / 2, 2)); }