AccessScanRun a free scan

Guide

Building an Accessible Color Palette That Actually Passes

An accessible color palette is not a separate, watered-down version of your brand colours. It is a system where every text and UI pairing you ship has been checked against measurable contrast thresholds, where meaning is never carried by hue alone, and where combinations have been tested in context rather than swatch-against-swatch in a vacuum.

Most palettes look fine in a Figma board and fall apart in production: a brand blue that passes on white but fails on the grey card it actually sits on, a 'success green' that vanishes for a red-green colour-blind user, a placeholder grey that reads at 3:1 instead of 4.5:1. This guide walks designers through building a palette that holds up, with the specific ratios, failure modes, and testing workflow that matter.

Start from the contrast math, not the swatches

WCAG has three numbers worth memorising, and they are unchanged in WCAG 2.2. Under SC 1.4.3 Contrast (Minimum), normal body text needs a contrast ratio of at least 4.5:1 against its background. Large text (at least 18pt, or 14pt bold, roughly 24px and 18.66px bold) needs 3:1. Under SC 1.4.11 Non-text Contrast, UI elements such as input borders, toggle states, focus rings, meaningful icons, and chart segments also need 3:1 against adjacent colours.

Contrast is calculated from relative luminance, not from how different two colours 'feel'. This is why two vivid, saturated colours like a hot pink on a teal can look loud yet measure below 3:1, while a muted dark grey on off-white sails past 4.5:1. Saturation and hue barely move the ratio; lightness difference is what does. Build your palette around a disciplined lightness scale and the ratios tend to fall into place.

A practical move: generate each brand colour as a 10- or 11-step tonal ramp (50 through 950) and record the contrast of each step against both white and your darkest neutral. You will quickly see which steps are 'text-safe' and which are decoration-only. For the full breakdown of thresholds and how large-text and UI rules differ, see the color contrast requirements guide.

Define palette roles, then pair them deliberately

Accessibility lives in pairings, not in individual colours. A hex value has no contrast ratio by itself; only a foreground-on-background pair does. So design your palette as roles, and lock the valid pairings for each.

  • Text-on-surface: every body-text token must clear 4.5:1 on every surface it can land on. A token that passes on your white background but fails on your light-grey card surface is two different results, not one.
  • Interactive states: hover, active, focus, visited, disabled. Disabled controls are exempt from contrast minimums, but do not lean on that, because a 'disabled-looking' grey is often applied to things users can still interact with.
  • Semantic colours: success, warning, error, info. These carry meaning, so they are held to non-text contrast (3:1) where they form borders or icons, and to text contrast where they colour words.
  • Focus indicators: under WCAG 2.2, focus has its own pressures. The focus ring should reach 3:1 against the background (SC 1.4.11), and SC 2.4.11 Focus Not Obscured (Minimum), new in 2.2 at Level AA, means the focused element must not be entirely hidden behind sticky headers or overlays.

Write these pairings into your design tokens. 'text.primary on surface.raised clears AA' is a contract a developer can honour; 'use the dark grey' is not.

Never rely on colour alone

WCAG SC 1.4.1 Use of Color (Level A) requires that colour is never the only visual means of conveying information, indicating an action, prompting a response, or distinguishing an element. This is the rule designers break most often, and it is independent of contrast: a pairing can pass 4.5:1 and still fail 1.4.1.

Concrete failures and their fixes:

  • Form validation that turns a field red with no error text or icon. Add an inline message and an icon; the red becomes reinforcement, not the sole signal.
  • Links distinguished from body text by colour only. Underline them, or guarantee both a 3:1 contrast against surrounding text and a non-colour cue on hover and focus.
  • Charts and legends that map data series to colour swatches alone. Add direct labels, patterns, or distinct markers so a colour-blind reader can tell the lines apart.
  • Required fields shown by a coloured label. Add an asterisk or the word 'required'.
  • Status pills (green 'Active', red 'Failed') that rely on fill colour. Add a text label or icon shape inside the pill.

Colour-vision deficiency, most commonly red-green, affects a meaningful share of users, particularly men. Designing redundant cues is not an edge-case accommodation; it also helps anyone reading a dim phone screen in bright sunlight.

Test combinations in context, not in isolation

Swatch-on-swatch checking misses the situations that actually break. Test the way your colours appear on the real screen.

  • Test text on every surface it can render on: white, raised cards, tinted section backgrounds, and over image overlays. Text over photos is a classic failure; if you cannot guarantee the pixels behind the text, add a scrim or solid plate.
  • Check both light and dark themes. A palette inverted for dark mode rarely keeps its ratios; pure white text on a near-black surface can be uncomfortably harsh, while mid-grey text often drops below 4.5:1.
  • Verify interactive states, not just the resting state. Hover and focus colours are frequently lighter and quietly fail.
  • Simulate colour-vision deficiencies (protanopia, deuteranopia, tritanopia) to confirm your semantic colours stay distinguishable.
  • Respect SC 1.4.12 Text Spacing and SC 1.4.13 Content on Hover or Focus: tooltips and popovers that appear on hover must themselves meet contrast and stay dismissable, hoverable, and persistent.

Run real pairings through a checker as you design. AccessScan's contrast checker gives you the ratio and the pass or fail for normal text, large text, and UI components in one place, and a full-page free scan flags low-contrast pairings on your rendered site, where the broken ones actually hide.

Why this matters beyond good taste

Contrast and use-of-colour are not optional polish. Under the European Accessibility Act (Directive (EU) 2019/882), which applies from 28 June 2025, many products and services must meet WCAG 2.2 Level A and AA via the EN 301 549 standard, and 1.4.1, 1.4.3, and 1.4.11 sit squarely in that baseline. In the US the ADA names no specific WCAG version, but 2.1/2.2 Level AA is the de-facto bar, and Section 508 (Revised) and Canada's AODA both reference WCAG 2.0 Level AA. A palette that fails contrast is a compliance gap, not just an aesthetic one.

Bake the rules into your design system once and every screen inherits them. Pair your palette work with the focus and indicator rules in the guide to visible focus indicators, and the broader criteria in the WCAG reference.

Check your site against AccessScan

See your issues ranked by impact in seconds — free.

Run a free accessibility scan

FAQ

What contrast ratio does an accessible color palette need?

At minimum 4.5:1 for normal body text (SC 1.4.3), 3:1 for large text (at least 18pt, or 14pt bold), and 3:1 for non-text UI elements like borders, icons, and focus rings (SC 1.4.11). These are the WCAG Level AA thresholds, unchanged in WCAG 2.2.

Can a color pairing pass contrast but still fail accessibility?

Yes. Contrast (SC 1.4.3) and use of colour (SC 1.4.1) are separate requirements. A red error field can meet 4.5:1 yet still fail if colour is the only signal. Always add a second cue such as text, an icon, or an underline.

Do brand colours have to change to be accessible?

Not usually. Keep your brand hues for decoration and large display elements, and derive text-safe tints and shades from the same colours for body copy and UI. A tonal ramp lets you keep the brand identity while meeting contrast where it counts.

How do I test a palette for colour-blind users?

Simulate protanopia, deuteranopia, and tritanopia, then confirm your semantic colours (success, warning, error) remain distinguishable and that no information is carried by hue alone. Direct labels, patterns, and icons keep meaning intact regardless of colour perception.

Is checking swatches in my design tool enough?

No. Swatch-on-swatch checks miss real failures like text over images, tinted card surfaces, hover states, and dark mode. Test pairings as they render in context and scan the live page to catch combinations that only break in production.

More guides