A11y Canvas
← Colour
ColourYuliana Krasulya

Colour: What Contrast Measures, What the Eye Feels

A contrast ratio of 4.5:1 is necessary — but it's not enough. Optical vibration, colour blindness, visual fatigue in dark mode: these are all phenomena that WCAG 2.1 doesn't measure. This guide covers both dimensions of chromatic accessibility — ratios and perception — including combinations to avoid, ones that hold up over time, and what WCAG 3.0 is preparing.

When chromatic accessibility comes up, the immediate reflex is to open a contrast checker. 4.5:1 for regular text, 3:1 for large text — box ticked, move on. Except that ratio only tells part of the story.

WCAG measures the difference in relative luminance between two colours. The human eye, however, interprets much more: optical vibration between two saturated hues, the confusion induced by colour blindness, the fatigue caused by a background that "jumps" visually. A colour combination can pass every test and still be unpleasant to look at for more than three seconds.

This article covers both dimensions — the measurable and the perceptual — to give you a complete picture of what works, and why.


What WCAG measures (and why it's necessary but not sufficient)

The WCAG 2.1 standard defines three contrast levels for text:

  • Level AA (minimum): 4.5:1 for normal text, 3:1 for large text (18pt+ or 14pt+ bold)

  • Level AAA (enhanced): 7:1 for normal text, 4.5:1 for large text

  • UI components and graphics: 3:1 minimum (buttons, informative icons, meaningful borders)

The calculation is based on relative luminance — a value between 0 (absolute black) and 1 (pure white) that accounts for the non-linearity of human brightness perception. The ratio (L1 + 0.05) / (L2 + 0.05) yields a number between 1:1 (no contrast) and 21:1 (black on white).

This model is robust for measuring basic legibility. But it doesn't account for:

  • Chromatic confusion: two colours that are very different in hue can have nearly identical luminance for a colour-blind user.

  • Optical vibration (chromostereopsis): certain pairs of saturated colours create an illusion of movement or depth that exhausts the eyes.

  • Size and context: small white text on a dark purple background can technically pass AA while remaining painful to read on a low-resolution screen.


Combinations to avoid

Red + green

The worst mistake in interface design. Around 8% of men and 0.5% of women have deuteranomaly or protanomaly — the two most common forms of colour blindness, which affect precisely the perception of red and green. For these users, the two colours can appear identical or nearly indistinguishable.

The concrete problem: using red exclusively for errors and green for successes, with no accompanying icon or text. This is one of the most documented anti-patterns in digital accessibility.

The rule: colour must never be the sole carrier of information. Always pair it with an icon, a label, a pattern, or a typographic style.

Light grey on white (and any pale-on-pale combination)

One of the most common flaws in today's "minimalist" interfaces. Text at #9CA3AF on a #FFFFFF background gives a ratio of around 2.5:1 — well below the AA minimum. Yet this combination is ubiquitous in modern UI kits, frequently used for placeholders, secondary labels, and help text.

The problem worsens with age (contrast sensitivity naturally declines), eye strain, a low-quality screen, or a bright environment.

The threshold to remember: if you can't read the text while squinting slightly, it probably doesn't pass AA.

Bright yellow on white

#FFFF00 on #FFFFFF is visually aggressive and yet the contrast is catastrophic (1.07:1). This is the trap of "vivid" colours: high saturation doesn't compensate for a luminance close to that of the background. Pure yellow is one of the most luminous colours in the visible spectrum — placing it on white makes it nearly invisible.

Blue + red (and saturated "primary" pairs)

The blue channel is poorly served by the human retina: S-cones (sensitive to blue) are fewer in number than M and L cones, and their spatial resolution is lower. Pure blue text on a red background — or the reverse — produces a "chromatic blur" and vibration effect that makes reading physically uncomfortable.

More broadly, any pair of complementary colours at maximum saturation (blue/orange, purple/yellow, green/magenta) triggers a phenomenon called chromostereopsis: the brain attempts to "focus" on two different wavelengths simultaneously, creating an illusion of depth or trembling. The result: eye strain, and sometimes headaches.

Penn State Accessibility sums it up well: "Vibrating color combinations should be avoided because they can cause headaches and make content virtually unreadable."


Combinations that work

Very dark text on very light background (and vice versa)

The canonical combination. Pure black #000000 on pure white #FFFFFF gives 21:1 — the theoretical maximum. In practice, most design systems prefer to soften slightly:

  • Text #1A1A1A on background #FAFAFA → ratio ~19:1, less fatigue for extended reading

  • Text #0B0F1F on background #FDFDFD → same effect, slight cool tint

This works for everyone: colour-blind users, low-vision users, users on low-end screens.

Dark blue on white or cream

#003366 on #FFFFFF (ratio ~12:1) is the gold-standard trust choice. Banks, public services, medical interfaces: it's no coincidence. The blue hue doesn't interfere with red-green colour blindness, luminance is high, and the psychological connotation (reliability, professionalism) reinforces perceived legibility.

Well-calibrated dark mode

The temptation in dark mode is to go to extremes: background #000000, text #FFFFFF. That's a mistake. Pure white on absolute black creates halation — a glowing halo effect that makes reading fatiguing, particularly for users with astigmatism.

Current recommendations converge on:

  • Background: between #0D0D0D and #1A1A1A

  • Primary text: #E8E8E8 or #EAEAEA — never pure white

  • Secondary text: around #9B9FAA

For data and charts

Monochromatic or sequential palettes (luminance variations on a single hue) are more robust than rainbow palettes. ColorBrewer, designed for scientific cartography, remains a solid reference: it offers palettes tested for colour blindness and greyscale printing.

General rule: never distinguish two categories by hue alone. Vary luminance, shape, and pattern as well.


What WCAG doesn't check yet

The current standard has a recognised limitation: it treats all text of the same size identically, even though legibility also depends on context, font weight, and the nature of the background.

APCA (Advanced Perceptual Contrast Algorithm) is the method proposed for WCAG 3.0. It calculates a "lightness contrast" that accounts for reading direction (dark text on light background vs light text on dark background), typeface, and weight. Results can diverge significantly from WCAG 2.1 in certain cases — particularly light text on deep coloured backgrounds.

For a tool like Frontend Studio, integrating both metrics simultaneously provides far more complete information than a single WCAG ratio.


Practical checklist

Before validating any colour combination:

WCAG

  • Ratio ≥ 4.5:1 for body text

  • Ratio ≥ 3:1 for UI components and large text

  • Tested with a verification tool (WebAIM Contrast Checker, Colour Contrast Analyser)

Colour blindness

  • The combination doesn't rely on red/green as the sole information carrier

  • Tested via a colour blindness simulator (Coblis, Sim Daltonism, DevTools)

  • Every piece of colour-coded information is paired with an icon, text, or shape

Perception

  • No complementary pairs at maximum saturation side by side (vibration)

  • In dark mode, background and text avoid pure black and pure white

  • Readable without effort on a mid-range screen, in a bright environment


Resources

  • WCAG 2.1 — Understanding Contrast (Minimum) — W3C

  • Colors and Luminance — MDN Web Docs

  • Vibrating Colors — Penn State Accessibility

  • ColorBrewer — accessible data palettes

  • APCA Contrast Calculator — future WCAG 3.0 standard