Abstract WCAG contrast methodology workspace with dark and light sample panels, luminance ladders, color swatches, and pass/fail accessibility checks.

Methodology

How Hue Codex calculates WCAG contrast

Hue Codex uses WCAG 2.x relative luminance and contrast-ratio math for foreground/background checks, text recommendations, pair ranking, focus indicators, link states, gradients, opacity previews, and palette readability signals.

Standard Hue Codex heuristic Browser-dependent

Short answer

Hue Codex calculates contrast from sRGB relative luminance, compares the unrounded raw ratio against WCAG thresholds, and rounds only the displayed ratio. Contrast is treated as a strong readability signal, not a full accessibility guarantee.

  • Normal text AA requires 4.5:1, normal text AAA requires 7:1, large text AA requires 3:1, and large text AAA requires 4.5:1.
  • WCAG large text means at least 18pt normal text or 14pt bold text, approximately 24px and 18.5px respectively in CSS pixels.
  • Meaningful non-text UI cues, focus indicators, icons, and graphical objects use a 3:1 adjacent-color target.
  • Focus Ring Contrast checks adjacent-color contrast for the ring against page and component colors; it does not validate WCAG 2.2 Focus Appearance size, area, or focused-vs-unfocused state-change requirements.
  • Pass/fail logic uses raw ratios before display rounding, so near-threshold values are not rounded into a pass.
  • Contrast does not prove usability by itself; text size, font weight, placement, state cues, and non-color signals still matter.

Standards status

These badges identify which parts of this methodology are standards-backed, draft-track, Hue Codex-specific, approximate, or dependent on browser behavior.

Standard Hue Codex heuristic Browser-dependent
Standard Stable standard or standards-backed behavior used as authority, such as WCAG 2.2 and broadly implemented CSS Color 4 behavior.
Hue Codex heuristic Hue Codex ranking, role hints, bands, labels, or workflow guidance rather than an external standard.
Browser-dependent Output depends on browser APIs, rendering, color management, canvas pixels, clipboard, download, or CSS support.

Formulas, choices, heuristics, and limits

This separates standards-based formulas from Hue Codex implementation decisions, product heuristics, and known limitations for this methodology.

Standards-based formulas

Formula, threshold, syntax, or data behavior taken from a cited standard or standards-backed source.

  • WCAG relative luminance from encoded sRGB channels divided by 255, piecewise-linearized at the 0.04045 breakpoint, then weighted with 0.2126 red, 0.7152 green, and 0.0722 blue.
  • WCAG contrast ratio: (lighter luminance + 0.05) divided by (darker luminance + 0.05).
  • WCAG text and non-text thresholds: 4.5:1, 7:1, 3:1, and 4.5:1 for the relevant AA and AAA use cases.
  • WCAG non-text contrast uses 3:1 adjacent contrast for meaningful focus indicators; WCAG 2.2 Focus Appearance also defines separate size, area, and focused-vs-unfocused contrast requirements.

Implementation choices

How Hue Codex chooses to parse, normalize, round, export, or sequence calculations.

  • Parsed colors are normalized to opaque sRGB HEX before contrast math runs.
  • Opacity behavior is tool-specific: Contrast Checker expects resolved opaque colors, while Opacity Calculator composites the transparent foreground over the selected background before scoring.
  • Text contrast is evaluated from the source foreground and background colors, not sampled anti-aliased screenshot pixels.
  • Hue Codex compares raw ratios for pass/fail and rounds only the displayed ratio.

Hue Codex heuristics

Product rankings, bands, labels, suggestions, or role hints that are useful guidance but not external standards.

  • The all-checks recommendation and best single candidate ranking are product guidance, not a WCAG requirement.
  • Best text and accessible-pair suggestions rank candidates by raw contrast and HSL lightness distance from the source color.
  • Gradient and palette readability signals use sampled or candidate pairs to prioritize review work.

Known limitations

Caveats, edge cases, browser dependencies, approximations, or contexts the method does not prove.

  • Contrast alone does not prove accessibility or usability.
  • Anti-aliasing, thin type, images, texture, gradients, and final component placement can change real readability.
  • Anti-aliased or smoothed text can appear lower contrast than the nominal CSS/source color pair, especially with thin or unusual fonts.
  • Focus Ring Contrast checks adjacent-color contrast only; it does not validate the full WCAG 2.2 Focus Appearance size, area, or state-change requirements.
  • Disabled controls, logos, incidental text, and decorative content can have WCAG exceptions that require judgment.

Inputs and normalization

Standard Approximation Browser-dependent

Contrast tools accept parsed sRGB colors from HEX, RGB-style CSS input, HSL-style input, Lab/LCH, OKLab/OKLCH, and tool-generated colors. Every accepted input is normalized to an opaque sRGB HEX value before contrast math runs.

Opacity behavior is tool-specific. Contrast Checker expects resolved opaque foreground and background colors; it does not composite transparent color input. Opacity Calculator composites the transparent foreground over the selected background, then calculates contrast for the effective color pair. Gradient contrast is sampled from representative gradient stops and midpoint colors, so it is a warning signal rather than proof for every pixel.

Tool-specific opacity behavior.
Tool Opacity handling What to enter or review
Contrast Checker Does not composite transparent colors Enter the resolved opaque foreground and background colors for the final rendered state
Opacity Calculator Composites the transparent foreground over the selected background before contrast checks Review the resolved color, overlay visibility, and text contrast on the composited result

Formula and thresholds

Standard

Relative luminance is calculated by converting each 8-bit sRGB channel into a 0 to 1 encoded value, applying the WCAG sRGB linearization curve, then weighting the linear red, green, and blue channels with 0.2126, 0.7152, and 0.0722.

The WCAG 2.2 breakpoint for the piecewise sRGB channel conversion is 0.04045. Older WCAG references sometimes show 0.03928; Hue Codex uses 0.04045.

Contrast ratio is (lighter luminance + 0.05) divided by (darker luminance + 0.05).

Hue Codex compares the raw ratio with the target threshold. The displayed ratio is rounded to two decimal places for readability, but the raw value decides pass or fail.

Text contrast is evaluated from the source foreground and background colors obtained from the user agent, markup, or stylesheets, not from anti-aliased screenshot pixels. Anti-aliasing, font smoothing, thin strokes, and unusual fonts can make rendered text appear fainter than the nominal CSS color pair.

WCAG defines large-scale text as at least 18pt normal text or 14pt bold text, or equivalent size for CJK fonts. W3C Understanding SC 1.4.3 gives the CSS conversion as 1pt = 1.333px, so 18pt is approximately 24px and 14pt is approximately 18.5px.

WCAG relative luminance formula
For each 8-bit sRGB channel C8:
  CsRGB = C8 / 255

  if CsRGB <= 0.04045:
    Clinear = CsRGB / 12.92
  else:
    Clinear = ((CsRGB + 0.055) / 1.055) ^ 2.4

L = 0.2126 * Rlinear + 0.7152 * Glinear + 0.0722 * Blinear

contrast_ratio = (max(Lforeground, Lbackground) + 0.05)
               / (min(Lforeground, Lbackground) + 0.05)
WCAG contrast thresholds used by Hue Codex.
Use case AA target AAA target
Normal text 4.5:1 7:1
Large text: 18pt normal or 14pt bold 3:1 4.5:1
UI components and graphical objects 3:1 Not scored by Hue Codex

Focus ring checks

Standard Hue Codex heuristic

WCAG 1.4.11 Non-text Contrast applies a 3:1 adjacent-color contrast target to visual information required to identify component states, including authored focus indicators.

WCAG 2.2 SC 2.4.13 Focus Appearance is a separate Level AAA criterion. It requires a visible focus indicator area at least as large as a 2 CSS pixel thick perimeter of the unfocused component or sub-component, and a 3:1 contrast change between the same pixels in the focused and unfocused states.

The Hue Codex Focus Ring Contrast tool checks contrast only: ring color against the page background and ring color against the component fill. It does not calculate focus-indicator area, prove the 2px perimeter-equivalent size, evaluate focused-vs-unfocused pixel changes, check obstruction, or verify that every keyboard-focusable component has a visible indicator.

What the Focus Ring Contrast tool does and does not validate.
Requirement area Hue Codex check Remaining manual review
Adjacent contrast Checks ring versus page and ring versus component against the 3:1 UI/non-text target Verify the actual adjacent colors in every final state and theme
Focus Appearance size and area Not validated as conformance Confirm the indicator area meets or exceeds the 2 CSS pixel perimeter-equivalent requirement
Focused versus unfocused state change Not validated as conformance Compare same pixels between focused and unfocused states and confirm the required 3:1 change
Focus visibility and coverage Not validated as conformance Test every keyboard-focusable component, focus-visible behavior, obstruction, offset, shape, and responsive state

Recommendation logic

Hue Codex heuristic

Best text suggestions compare candidate foreground colors against the selected background and rank them by raw contrast ratio. Adjustment helpers search HSL lightness steps from 0 to 100 in 0.1 increments while preserving the source HSL hue and saturation values.

For opaque contrast suggestions, Hue Codex chooses the passing candidate with the lowest raw ratio that still meets the requested target. Ties are broken by the smallest absolute HSL lightness distance from the source color. If raw ratio and distance are both tied, the earlier dark-to-light candidate remains selected.

The all-checks recommendation uses 7:1 as a Hue Codex product heuristic for choosing one strict candidate across common text scenarios. It is not a separate WCAG category.

Accessible pair finding ranks foreground/background combinations by pass state and contrast. The ranking is useful for screening palettes, but final roles still need real component review.

  • Search direction: dark to light, evaluating lightness 0.0, 0.1, 0.2, ... 100.0 without stopping early.
  • Hue and saturation: copied from the normalized source HSL value; only HSL lightness changes during the search.
  • Clamping and rounding: hue is normalized, saturation and lightness are clamped to valid HSL ranges, then RGB channels are rounded and clamped into six-digit sRGB HEX.
  • Closest means absolute HSL lightness distance from the source color, measured in percentage points; it does not mean Delta E, RGB distance, or OKLCH distance.
  • Fallback: if no candidate reaches the target, Hue Codex returns the strongest raw-contrast candidate and marks the suggestion as best effort.
Hue Codex recommendation heuristics.
Recommendation Target Status
All-checks recommendation 7:1 Hue Codex heuristic; useful when a single strict candidate is preferred

Edge cases and limits

Standard Browser-dependent
  • A ratio of 4.499:1 does not pass a 4.5:1 threshold, even if it displays near 4.5 after rounding.
  • Hue Codex uses source colors for contrast math. Anti-aliased screenshots and subpixel-rendered glyph edges are not sampled as the pass/fail source of truth.
  • Anti-aliasing, thin type, image text, textured backgrounds, and gradients can reduce practical readability.
  • Disabled controls, logos, brand marks, and incidental text can have different WCAG treatment than ordinary readable UI text.
  • Color contrast does not replace labels, icons, focus visibility, state affordances, or color-vision review.

Validation checks

Standard Hue Codex heuristic
Real HEX contrast checks used to validate threshold boundaries.
Pair Raw ratio Expected result
#000000 on #FFFFFF 21:1 Maximum sRGB contrast; AA normal and UI/non-text pass
#FFFFFF on #FFFFFF 1:1 Same foreground and background; contrast thresholds fail
#767676 on #FFFFFF 4.542224959605253:1 AA normal passes because raw value is at least 4.5
#777777 on #FFFFFF 4.478089453577214:1 AA normal fails because raw value is below 4.5
#949494 on #FFFFFF 3.0334698257384747:1 UI/non-text passes because raw value is at least 3
#959595 on #FFFFFF 2.9953461357088114:1 UI/non-text fails because raw value is below 3

Equations and suggestion pseudocode

Standard Hue Codex heuristic

These equations and steps are the reproducible contrast path. The suggestion algorithm is a Hue Codex heuristic layered on top of the standards-based contrast formula.

WCAG contrast equations
srgb_to_linear(channel_8bit):
  v = channel_8bit / 255
  if v <= 0.04045:
    return v / 12.92
  return ((v + 0.055) / 1.055) ^ 2.4

relative_luminance(hex):
  r, g, b = hex_to_rgb(hex)
  return 0.2126 * srgb_to_linear(r)
       + 0.7152 * srgb_to_linear(g)
       + 0.0722 * srgb_to_linear(b)

contrast_ratio_raw(foreground, background):
  fg = relative_luminance(foreground)
  bg = relative_luminance(background)
  lighter = max(fg, bg)
  darker = min(fg, bg)
  return (lighter + 0.05) / (darker + 0.05)

wcag_score(foreground, background):
  raw = contrast_ratio_raw(foreground, background)
  return {
    display_ratio: round(raw, 2),
    normal_AA: raw >= 4.5,
    normal_AAA: raw >= 7,
    large_AA: raw >= 3,
    large_AAA: raw >= 4.5,
    ui_AA: raw >= 3
  }
Contrast suggestion search for opaque pairs
suggest_minimum_contrast_color(target, fixed, minimum_ratio = 7):
  target_hex = normalize_hex(target)
  fixed_hex = normalize_hex(fixed)
  target_hsl = rgb_to_hsl(hex_to_rgb(target_hex))
  best = null
  fallback = null

  # Search direction is dark to light.
  # Step size is 0.1 HSL lightness from 0.0 through 100.0.
  # Hue and saturation are copied from target_hsl for every candidate.
  # hsl_to_rgb normalizes hue, clamps s/l to valid ranges,
  # rounds RGB channels, and rgb_to_hex clamps to displayable sRGB.
  for step from 0 to 1000 inclusive:
    lightness = step / 10
    candidate = rgb_to_hex(hsl_to_rgb({
      h: target_hsl.h,
      s: target_hsl.s,
      l: lightness
    }))
    raw = contrast_ratio_raw(candidate, fixed_hex)
    distance = abs(lightness - target_hsl.l)
    # "Closest" means this absolute HSL lightness distance,
    # not Delta E, RGB distance, or OKLCH distance.

    # Fallback chooses strongest available raw contrast.
    # Tie-breaker: closest HSL lightness to the source.
    # Exact ties keep the earlier dark-to-light candidate.
    if fallback is null
       or raw > fallback.raw
       or (raw == fallback.raw and distance < fallback.distance):
      fallback = {candidate, raw, distance, lightness}

    # Opaque passing candidate chooses the lowest raw passing ratio.
    # Tie-breaker: closest HSL lightness to the source.
    # Exact ties keep the earlier dark-to-light candidate.
    if raw >= minimum_ratio:
      if best is null
         or raw < best.raw
         or (raw == best.raw and distance < best.distance):
        best = {candidate, raw, distance, lightness}

  if best exists:
    return best with possible = true
  return fallback with possible = false

Reproducible test vectors

Standard Hue Codex heuristic

These vectors use the WCAG relative-luminance formula and compare unrounded raw ratios against the relevant threshold. Displayed ratios can round to two decimals, but pass/fail must use the raw value.

WCAG contrast boundary vectors.
Input Expected raw ratio Threshold result
#000000 on #FFFFFF 21:1 Maximum sRGB contrast; AA normal and UI/non-text pass
#FFFFFF on #FFFFFF 1:1 Same foreground and background; contrast thresholds fail
#767676 on #FFFFFF 4.542224959605253:1 AA normal passes because raw value is at least 4.5
#777777 on #FFFFFF 4.478089453577214:1 AA normal fails because raw value is below 4.5
#949494 on #FFFFFF 3.0334698257384747:1 UI/non-text passes because raw value is at least 3
#959595 on #FFFFFF 2.9953461357088114:1 UI/non-text fails because raw value is below 3

Sources and standards

These references anchor the public standards and formats used by Hue Codex. Status badges distinguish stable standards, drafts, Hue Codex heuristics, approximations, and browser-dependent behavior.

Tools using this methodology

These Hue Codex tools link to this methodology because they depend on the formulas, assumptions, limits, or data policy described here.