Skip to content
Aback UI

AccessibilityColor

WCAG colour contrast for UI developers

The WCAG 2.2 contrast rules in practice: 4.5:1 and 3:1, large text, non-text contrast for borders and focus rings, and the mistakes that fail audits.

By the Aback UI teamPublished 7 min read

WCAG 2.2 Level AA requires a contrast ratio of at least 4.5:1 for normal text, 3:1 for large text, and 3:1 for the visual parts of interface components and meaningful graphics, such as input borders, icons, and focus indicators. Level AAA raises text to 7:1 and 4.5:1. The ratios are minimums with no rounding, and they apply in every theme you ship.

What contrast ratios does WCAG 2.2 require?

ContentSuccess criterionLevelMinimum ratio
Normal text and images of text1.4.3 Contrast (Minimum)AA4.5:1
Large text1.4.3 Contrast (Minimum)AA3:1
Normal text1.4.6 Contrast (Enhanced)AAA7:1
Large text1.4.6 Contrast (Enhanced)AAA4.5:1
UI components and graphical objects1.4.11 Non-text ContrastAA3:1

Most product teams and most accessibility requirements target Level AA. The criteria and their exceptions are defined in the WCAG 2.2 specification (opens in a new tab), and the W3C's Understanding 1.4.3 (opens in a new tab) page explains the intent behind them.

How is the contrast ratio calculated?

The ratio compares the relative luminance of the lighter colour (L1) with the darker colour (L2):

ts
contrast = (L1 + 0.05) / (L2 + 0.05)

Relative luminance is computed from linearised sRGB channels, weighted by how sensitive the eye is to each: green counts most and blue least. The result ranges from 1:1 (identical colours) to 21:1 (black on white).

Some consequences worth knowing:

  • Hue barely matters; luminance does. A saturated blue and a grey can have the same ratio against white.
  • Brand colours are often mid-luminance. Aback Blue, #009bf9, is 2.98:1 on white. It cannot carry body text in the light theme, so Aback UI uses the darker #005d95 for links, which is 7.00:1. In the dark theme, links use #33b7ff, which is 8.82:1 on the #0a0a0a background.
  • Transparency must be flattened first. A colour with alpha has no fixed contrast until you composite it over the actual background.

You do not need to compute this by hand. The contrast checker accepts HEX, RGB, HSL, and OKLCH, handles transparency, and reports AA and AAA results for text and non-text contrast.

What counts as large text?

WCAG defines large text in points: at least 18pt, or at least 14pt when bold. In CSS pixels that is 24px for regular weight and about 18.66px for bold. A few clarifications:

  • A 16px or 18px semibold label is not large text, even if it looks prominent. It needs 4.5:1.
  • "Bold" means a heavy weight, typically 700. A 500 or 600 weight is safer treated as regular.
  • Thin, decorative, or very condensed fonts can be harder to read than their size suggests. The ratio is a minimum, not a guarantee of legibility.

Non-text contrast: borders, icons, and focus rings

Success criterion 1.4.11 asks for 3:1 against adjacent colours for visual information that is needed to identify a component or its state, and for parts of graphics needed to understand them. In practice:

ElementNeeds 3:1?
A text input whose border is the only thing showing where it isYes, the border
A button with a filled background and a text labelThe text needs 4.5:1; the fill boundary is not required if the label identifies it
Checkbox, radio, and switch outlines and their checked statesYes
Icon-only buttonsYes, the icon
Focus indicatorsYes
Chart lines and segments that carry dataYes, or provide the data another way
Decorative dividers and card bordersNo, if nothing depends on them

Focus indicators deserve extra care. A focus ring has to be visible against whatever it sits on, in every theme. Aback UI's light-theme focus ring, #007cc7, is 4.46:1 on white: comfortably above 3:1 for a ring, but just below 4.5:1, which is why the same blue is not used for body-size text. WCAG 2.2 also adds 2.4.11 Focus Not Obscured (Minimum) at Level AA, which requires that a focused element is not entirely hidden by sticky headers or other author-created content, and 2.4.13 Focus Appearance at Level AAA, which sets a minimum size and contrast change for the indicator.

What is exempt?

  • Inactive components. Disabled controls and their text are exempt. Make the disabled state recognisable by more than colour, for example with reduced emphasis plus the native disabled attribute.
  • Incidental text. Text that is pure decoration, not visible, or part of a picture with significant other content.
  • Logotypes. Text that is part of a logo or brand name has no contrast requirement.

Placeholder text is not exempt. If it is visible and conveys information, it is text and needs 4.5:1, which is one more reason not to use a placeholder as a label.

Mistakes that fail audits

Rounding up

#777777 on white is 4.48:1 and fails. #767676 is 4.54:1 and passes. The thresholds are exact; a tool that shows "4.5:1" for both is hiding the answer.

Opacity on text

Fading text with opacity lowers its contrast in a way that is easy to miss in a design file. Near-black #0a0a0a at 50% opacity on white composites to about #858585, which is 3.69:1 and fails for normal text. Use a dedicated muted text colour that has been checked, such as Aback UI's text-muted-foreground, rather than a transparency utility.

Checking only against white

Muted text is usually checked against the page background and then placed on a tinted surface. #737373 is 4.74:1 on #ffffff but 4.35:1 on #f5f5f5. Check secondary text against every surface it appears on: cards, table stripes, sidebars, selected rows, and hover states.

Forgetting dark mode

Every pair needs checking in each theme. Dark themes tend to fail on muted text, on links that reuse the light theme's brand shade, and on focus rings. Pick dark values separately rather than inverting the light ones.

Colour as the only signal

Passing contrast is not enough when colour carries meaning. A red border alone does not communicate an error to someone who cannot distinguish red; add an icon or message. That is a separate criterion, 1.4.1 Use of Color.

Text over images and gradients

Contrast must hold at the worst point under the text. Add a solid or scrimmed background behind the text rather than hoping the image cooperates.

Checking a design system palette

In a design system, check pairs of roles once instead of checking every screen. List each foreground role with each background role it is allowed on, in both themes, and record the ratios:

Pair (light theme)RatioNormal text AA
#0a0a0a on #ffffff19.80:1Pass
#737373 on #ffffff4.74:1Pass
#005d95 on #ffffff7.00:1Pass
#009bf9 on #ffffff2.98:1Fail

These are values from Aback UI's design tokens; the full palette, with each colour in HEX, RGB, HSL, and OKLCH, is on the colors page. When you change a brand colour, the theme generator derives link, focus, and fill roles from it and checks their contrast for light and dark together, and the theming guide shows where to apply the overrides.

Automated checks are a start, not a verdict

Contrast is one of the few accessibility properties a tool can measure precisely, but tools only see the pairs you give them. Hover states, focus states, and text over images still need a person to check them.

If you are building the scale itself, OKLCH colours in CSS explains why perceptual lightness makes contrast more predictable from one step to the next, and the Tailwind colour scale generator shows the contrast of every shade on white and black.

Frequently asked questions

What contrast ratio does WCAG 2.2 AA require for text?

At least 4.5:1 for normal text and 3:1 for large text, under success criterion 1.4.3 Contrast (Minimum). Level AAA, criterion 1.4.6, raises these to 7:1 and 4.5:1.

Can I round 4.47:1 up to 4.5:1?

No. The thresholds are minimums, and a ratio just below 4.5:1 fails. Report ratios with enough precision to see which side of the threshold they fall on.

Do disabled buttons need to meet contrast requirements?

No. WCAG exempts text and components that are part of an inactive user interface component. They should still be recognisable as disabled, and that state should not rely on colour alone.

Is APCA required for WCAG compliance?

No. WCAG 2.2 measures contrast with the contrast ratio formula. APCA is an alternative method that has been explored for a future WCAG version, which is not a published standard.

Share this post

Try Aback UI in your project

Accessible React components you install as source. MIT licensed.

Get started