Perceivable · Level AA · 1.4.11
Non-text Contrast
The visual boundaries and states of active UI components — input borders, checkbox outlines, toggle fills, custom control states — and any graphics required to understand content need at least 3:1 contrast against their adjacent background. That's a lower bar than text (4.5:1), but it's a real one, not 'any color at all.'
- Low vision
- Color blindness
How to recognize it
Look at form field borders, checkbox and radio outlines, toggle switches, and icon-only buttons whose only boundary is a subtle background-color change, and check each against what's directly behind it. The most common failure is a pale gray input border on a white background (#e5e5e5-style grays land around 1.2:1) — visible enough for someone with typical vision scanning quickly, invisible to someone with low vision or reduced contrast sensitivity. A related failure: a custom checkbox or toggle where checked and unchecked states are distinguished only by a faint fill difference, so the state itself is hard to perceive, not just the boundary. It also applies to graphics — a chart's axis lines or a diagram's boundaries, when the shape or divisions genuinely need to be seen to understand the content. It does not apply to disabled controls, logos, purely decorative graphics, or content required to look exactly as it is (a photo, a screenshot) — those are explicitly exempt.
How to fix it
Give interactive component boundaries and state indicators at least 3:1 contrast against whatever's immediately behind them — a mid-gray like #6b7280 clears that easily on a white background, where a pale #e5e5e5 doesn't. For a checkbox or toggle, make sure the checked state is distinguishable by more than a subtle tint shift: a real color or fill change that itself passes 3:1 works, and pairing it with an icon or shape change (see 2.4.7's point about not relying on color alone) makes it even more robust. For essential graphics, apply the same 3:1 bar to whatever lines or boundaries carry the meaning — axis lines, section dividers, a graph's data boundary.
Example
Avoid
input {
border: 1px solid #e5e5e5; /* ~1.2:1 on white */
}.checkbox--checked {
border: 1px solid #eee;
background: #f5f5f5; /* barely different from unchecked */
}.chart-axis-line {
stroke: #eaeaea; /* the axis needed to read the chart, nearly invisible */
}Prefer
input {
border: 1px solid #6b7280; /* 4.8:1 on white */
}.checkbox--checked {
border: 1px solid #6b7280;
background: #b45309; /* clearly distinct fill, 5:1 on white */
}.chart-axis-line {
stroke: #6b7280; /* 4.8:1, clearly visible */
}