Skip to content
ColorKit

Free WCAG audit tool

WCAG contrast checker for a whole list of pairs

Free, no signup, and built for the audit rather than the single lookup: paste up to 100 pairs, one to a line, and each is judged against the success criterion its role calls for — 1.4.3 and 1.4.6 for text, 1.4.11 for icons, borders and controls. Rows that fail come back with a replacement color found by moving lightness in CIE LCH while hue and chroma stay put, so a brand color is corrected rather than abandoned, and rows nothing can save are named as background problems. The finished table copies out or downloads as a nine-column CSV.

  • 100% free
  • No signup
  • 100 pairs per run
  • 1.4.3 · 1.4.6 · 1.4.11
  • CSV export

5 of 100 rows read · 3 below their AA threshold · 2 of 4 text rows also clear 1.4.6

Press Ctrl+V anywhere on the page to drop in a list of pairs — it is appended to whatever is already here — no need to click the field first.

PairRatio1.4.3 AA1.4.6 AAA1.4.11Nearest pass
Aabody copy#1a1a1a on #ffffff · Body text
17.40:14.5:1 pass7:1 passnot in scopealready clears 4.5:1
Aaform help text#8a8a8a on #ffffff · Body text
3.45:14.5:1 fail7:1 failnot in scope
#767676text, L-8.04.57:1 · ΔE 8.0
Aaprimary button, large#ffffff on #2563eb · Large text
5.16:13:1 pass4.5:1 passnot in scopealready clears 3:1
Aainput border, ui#d1d5db on #ffffff · UI component
1.47:1not in scopenot in scope3:1 fail
#91959btext, L-23.53.00:1 · ΔE 23.5
Aawarning label#f59e0b on #ffffff · Body text
2.14:14.5:1 fail7:1 failnot in scope
#af6400text, L-22.54.52:1 · ΔE 28.4

How to audit a palette against WCAG

A list in, a criterion-by-criterion table out, with a fix attached to every failure.

  1. Paste the pairs you have to defend

    Put one pair on each line: the foreground first, the background second, then a label you will recognize in the export — “#8a8a8a on #ffffff — form help text”. The parser reads left to right and takes the first two colors it can resolve, so the arrows, commas and CSS variable names people leave in a copied list do no harm. A hundred lines are read per run; anything with fewer than two resolvable colors is listed back to you rather than dropped in silence.

  2. Tag the rows that are not body text

    Write large on a line for headings at 18pt or 14pt bold and above, and ui, icon, border or focus for anything that is not text at all. That word decides which success criterion governs the row: body and large text are judged under 1.4.3 and 1.4.6, while a component boundary or a meaningful icon is judged under 1.4.11 and has no AAA target, because 1.4.6 was never written for non-text.

  3. Take the repairs, then take the CSV

    Every row that misses its AA threshold gets a replacement color: lightness is walked along CIE LCH in half-point steps, in both directions, until the pair clears — hue and chroma stay where the brand put them, and the shift and the ΔE from the original are printed so you can argue the change with a designer. Copy the finished table or download it as a nine-column CSV, which is the shape an accessibility report expects.

Technical specifications

Line grammarForeground, background, then a free-text label. The first two resolvable colors on the line win, so “#fff on #2563eb — primary button” and “--brand-600: #2563eb / #ffffff” both parse
Role keywordslarge, heading, h1, h2, title or display mark a row as large text; ui, icon, border, outline, focus, control, graphic or non-text mark it as non-text; everything else is body text
Thresholds applied1.4.3 AA at 4.5:1 body and 3:1 large, 1.4.6 AAA at 7:1 body and 4.5:1 large, 1.4.11 AA at 3:1 for components and graphics. Non-text rows show a dash under 1.4.6, which does not cover them
Rows per run100 lines, blank lines skipped. Lines carrying fewer than two resolvable colors are reported back with their line number instead of being discarded
Repair searchCIE LCH lightness in 0.5 steps, tried in both directions and stopping at the first pass; hue and chroma held, the candidate clipped into sRGB, and the ratio recomputed from the clipped color
When no repair existsIf neither color can reach the threshold by lightness alone the row says so rather than offering something that does not work — every surface has a ceiling, and a #808080 one caps out at 5.32:1 even against pure black
Alpha in a listA translucent foreground is composited over the background on its own line; a translucent background is composited over white, because a pasted list carries no information about the page behind it
ExportNine quoted CSV columns — label, foreground, background, role, criterion, threshold, ratio, result, nearest pass — assembled in the browser and never posted anywhere

Frequently asked questions

What is the difference between 1.4.3 and 1.4.6?

They are the same measurement at two levels of strictness: 1.4.3 Contrast (Minimum) is level AA and asks for 4.5:1, or 3:1 once text is large; 1.4.6 Contrast (Enhanced) is level AAA and raises those to 7:1 and 4.5:1. Nothing else about them differs — same formula, same exemptions, same definition of large. A conformance claim is made at one level for whole pages, so a palette that meets 1.4.6 on nine rows and 1.4.3 on the tenth is an AA palette.

Do disabled buttons and placeholder text have to pass?

Disabled controls are exempt and placeholders are not. Both 1.4.3 and 1.4.11 carve out inactive components, so a greyed-out button with 2:1 text is conforming, however unhelpful it is. Placeholder text is ordinary text inside an active field, which means the pale grey almost every design system uses for it is a genuine 4.5:1 failure and one of the most common findings in a real audit.

Do I have to reach AAA?

Almost never — AA is what the law and the procurement documents point at. EN 301 549, the European public-sector standard, references WCAG 2.1 level AA, US Section 508 references level AA, and the ADA settlements that set expectations in the private sector do the same. W3C itself advises against requiring AAA for entire sites because some content cannot reach it. Treat the 1.4.6 column as a quality signal for body copy, not as the bar.

What exactly counts as a UI component under 1.4.11?

The visual information needed to identify a control and its state, and the parts of a graphic needed to understand it. In practice that is the boundary that tells you an input is an input, the tick inside a checkbox, the thumb of a toggle, the focus ring, and the segments of a chart that carry meaning. It is not decorative rules, drop shadows, background patterns, or a button's edge when the label inside already identifies it — and if a graphic's exact presentation is essential, such as a screenshot or a flag, it is exempt.

Does a brand color get an exemption?

The logotype does; the brand color does not. WCAG exempts text that is part of a logo or brand name from 1.4.3, and 1.4.11 exempts logos too, so a wordmark can stay exactly as the brand book draws it. The moment that same hue becomes a button fill, a link color or an icon in the interface it is ordinary content and is graded like everything else — which is why so many audits end with a second, darker version of the brand color reserved for text.

How is the nearest passing color chosen, and can I trust it?

It is your color with its lightness moved and its hue and chroma held, searched half a point at a time in CIE LCH and stopping at the first value that clears the threshold, so the result is the smallest lightness change that works rather than simply a darker shade. Two caveats. Highly saturated colors at extreme lightness fall outside sRGB and are clipped, which shifts the hue slightly — the printed ratio is recalculated from the clipped color, so it is honest, but the ΔE tells you how far the color travelled. And the ΔE is CIE76, which over-penalises saturated colors, so read it as a rank rather than a verdict.

Did WCAG 2.2 change any of the contrast numbers?

No. WCAG 2.2 became a W3C Recommendation in October 2023 and left 1.4.3, 1.4.6 and 1.4.11 exactly as they were in 2.1. It added 2.4.13 Focus Appearance at AAA, which asks for 3:1 between the focused and unfocused states of the same pixels and a focus indicator at least 2 CSS pixels thick, and it removed 4.1.1 Parsing. The rewrite that replaces the luminance ratio with a size-and-weight-aware model is WCAG 3, which is still a draft and is not what anyone is audited against.

About the three contrast criteria and what an audit needs

Three success criteria govern contrast and they are not interchangeable. 1.4.3 Contrast (Minimum) is the AA rule for text and images of text. 1.4.6 Contrast (Enhanced) is its AAA counterpart, same maths with the bar raised. 1.4.11 Non-text Contrast, added in WCAG 2.1 in 2018, is the AA rule for everything that is not text: the boundary that identifies a control, the states it can be in, and the parts of a graphic you need in order to understand it. All three exempt inactive controls and logotypes, and 1.4.11 additionally exempts a graphic whose exact presentation is essential. That is why this page grades by role rather than by pair — the same two hex codes are a pass as a chart segment and a failure as a caption, and a table that does not record which one you meant is not an audit, it is a list of numbers. When you want to interrogate a single pair instead, with the type rendered at four sizes, the color contrast checker is the tool for that job.

Auditing pair by pair is also the slow way to fix a palette. Failures cluster: one under-dark neutral ramp produces a dozen failing rows, and patching each one by hand leaves a palette with fourteen greys that nobody can maintain. Fix the ramp instead — a scale with evenly spaced perceived lightness, of the kind the color palette generator builds, gives you steps whose contrast against the surface is predictable rather than discovered. Two-hue pairings deserve particular suspicion: a hue and its opposite on the color wheel look maximally different and can sit at almost identical luminance, which is how a striking complementary color pairing lands at 1.8:1. And remember the rows a static palette never contains: hover, focus and visited states, dark mode, and the icon set — an icon owes 3:1 whether it is inline SVG or a raster exported through svg to png.

The repair column is deliberately conservative. Searching lightness in LCH rather than HSL matters because HSL lightness is not perceptual: two hues at the same HSL lightness can differ by more than 30 points of perceived lightness, so an HSL nudge changes the ratio by an unpredictable amount and usually overshoots. Holding chroma keeps the correction recognizable as the same color, which is the difference between a suggestion a brand team will accept and one they will not. The two limits worth knowing: at extreme lightness a saturated hue leaves the sRGB gamut and is clipped, which drifts the hue a little, and some pairs have no solution at all — against a mid grey no color reaches 7:1, because black itself only manages 5.32:1 there. When the column says the background has to move, that is arithmetic, not an opinion.

Where the pasted list goes

Every number on this page is worked out by JavaScript running in the tab you are reading it in. Nothing you type, paste or open is uploaded, logged or kept, which is also why the tools carry on working after you disconnect from the network.

The CSV is no exception: it is assembled from the table in memory and handed to your browser as a local download, so a client palette pasted here is never transmitted, and reloading the page clears the list.