Notes to Future-Me


Contrast Ratio for Text

Posted: 2025-11-05
Tags: Typography

The W3C provides guidance on minimal and ideal contrast ratio1 for text and background colors.

W3C Accessibility Guidelines

Contrast Ratio Guidelines

The W3C’s Web Content Accessibility Guidelines (WCAG) 2.0 provides the following guidelines:2

Text Type Minimum Enhanced
Normal Text 4.5:1 7:1
Large Text 3:1 4.5:1

Measurement Procedure3

  1. Measure the relative luminance of each letter (unless they are all uniform) using the formula:
    • L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G, and B are defined as:
      • if R_sRGB <= 0.03928 then R = R_sRGB /12.92 else R = ((R_sRGB +0.055)/1.055) ^ 2.4
      • if G_sRGB <= 0.03928 then G = G_sRGB /12.92 else G = ((G_sRGB +0.055)/1.055) ^ 2.4
      • if B_sRGB <= 0.03928 then B = B_sRGB /12.92 else B = ((B_sRGB +0.055)/1.055) ^ 2.4

      and R_sRGB, G_sRGB, and B_sRGB are defined as:

      • R_sRGB = R_8bit /255
      • G_sRGB = G_8bit /255
      • B_sRGB = B_8bit /255

The “^” character is the exponentiation operator.

Note: For aliased letters, use the relative luminance value found two pixels in from the edge of the letter.

  1. Measure the relative luminance of the background pixels immediately next to the letter using same formula.

  2. Calculate the contrast ratio using the following formula.
    • (L1 + 0.05) / (L2 + 0.05), where
      • L1 is the relative luminance of the lighter of the foreground or background colors, and
      • L2 is the relative luminance of the darker of the foreground or background colors.
  3. Check that the contrast ratio is equal to or greater than 7:1

Code4

// Source - https://stackoverflow.com/questions/9733288/how-to-programmatically-calculate-the-contrast-ratio-between-two-colors
// Posted by kirilloid
// Retrieved 2025-11-05, License - CC BY-SA 4.0

const RED = 0.2126;
const GREEN = 0.7152;
const BLUE = 0.0722;

const GAMMA = 2.4;

function luminance(r, g, b) {
  var a = [r, g, b].map((v) => {
    v /= 255;
    return v <= 0.03928
      ? v / 12.92
      : Math.pow((v + 0.055) / 1.055, GAMMA);
  });
  return a[0] * RED + a[1] * GREEN + a[2] * BLUE;
}

function contrast(rgb1, rgb2) {
  var lum1 = luminance(...rgb1);
  var lum2 = luminance(...rgb2);
  var brightest = Math.max(lum1, lum2);
  var darkest = Math.min(lum1, lum2);
  return (brightest + 0.05) / (darkest + 0.05);
}

console.log(contrast([255, 255, 255], [255, 255, 0])); // 1.074 for yellow
console.log(contrast([255, 255, 255], [0, 0, 255])); // 8.592 for blue

// note: minimal recommended contrast ratio is 4.5, or 3 for larger font-sizes