contrastRatio function

double contrastRatio(
  1. Object foreground,
  2. Object background
)

The WCAG 2.x contrast ratio between a foreground and an opaque background, in the range 1–21.

foreground and background are each an AstryxRgba or a CSS colour string that parseColor understands.

A translucent foreground is composited over the background first. A translucent background is rejected — composite it over its own backdrop before calling, because its rendered colour is unknowable here.

Throws an ArgumentError if either colour cannot be parsed, or if the background is translucent. Upstream throws a TypeError; Dart's TypeError carries no message, so the nearest idiomatic equivalent is used and the message text is preserved verbatim.

{@tool snippet}

contrastRatio('#000000', '#FFFFFF'); // 21

{@end-tool}

Implementation

double contrastRatio(Object foreground, Object background) {
  final bg = _resolve(background, 'background');
  if (bg.a < 1) {
    throw ArgumentError(
      'contrastRatio: background must be opaque — composite it over its '
      'backdrop first',
    );
  }
  var fg = _resolve(foreground, 'foreground');
  if (fg.a < 1) {
    fg = compositeOver(fg, bg);
  }
  final lumA = relativeLuminance(fg);
  final lumB = relativeLuminance(bg);
  final lighter = math.max(lumA, lumB);
  final darker = math.min(lumA, lumB);
  return (lighter + 0.05) / (darker + 0.05);
}