Free · No account · Client-side

Contrast checking, done right

Ratia checks WCAG 2.2 and APCA contrast for any color pair, suggests the nearest passing fix, and generates a shareable link — all in your browser, in under a second.

Open the Checker

Your brand color is #6BA8E8 on white. Does it pass for body text? Under WCAG 2.2 it lands at 2.48:1, short of the 4.5:1 floor for normal text. Under APCA the same pair scores Lc 47, short of the Lc 60 floor for body copy at 16px regular. Same answer, two algorithms. This page is how to pick which one governs.

Which standard applies to your project

Start with jurisdiction, not preference.

If you are shipping to the EU or to a US federal procurement target, WCAG 2.2 AA is binding. The European Accessibility Act took effect 28 June 2025 and references EN 301 549, which folds in WCAG 2.1 AA; most member states audit against 2.2. Section 508 references WCAG 2.0 AA, and the DOJ's April 2024 Title II rule cites 2.1 AA. None reference APCA. An auditor checks your work against a ratio, not a research preview.

If your project is a private design system with no statutory exposure, you have a real choice. APCA is a candidate algorithm in the WCAG 3.0 working draft, in development since 2021 and not expected to reach Recommendation before 2027. Adobe Spectrum, GitHub Primer, and the Open UI Community Group evaluate APCA internally; none have dropped WCAG 2.x. Picking APCA today is a research bet, not a compliance position.

The rule we apply when stress-testing token palettes: validate against WCAG 2.2 AA for the legal floor, then run APCA on anything that passes 2.2 only by a hair (4.5 to 5.2:1). That is the band where the two algorithms disagree most sharply.

The four AA thresholds and when each triggers

WCAG 2.2 AA is not one number. It is four, and applying the wrong one is the most common false pass we see in audits.

  • 4.5:1 for normal text. Body copy below 18pt regular or 14pt bold. SC 1.4.3.
  • 3:1 for large text. 18pt regular or 14pt bold and larger, roughly 24px regular or 18.66px bold in CSS. Same SC 1.4.3.
  • 3:1 for non-text UI components. Button borders, form outlines, checkbox glyphs, focus indicators, the icon inside a meaningful icon button. SC 1.4.11.
  • 3:1 for graphical objects conveying information. Chart series colors, status dots, pie slices against the page. Same SC 1.4.11.

The trap: a designer reads "3:1 for large text" and uses 3:1 everywhere a heading appears, including the 16px secondary label under it. The label is normal text. It needs 4.5:1.

Focus indicators trip people the same way. WCAG 2.4.11 (new in 2.2) requires the focus indicator be at least partially visible against the adjacent background. A 1px outline at 2.8:1 fails even if the button text passes.

When APCA Lc changes the answer

APCA, authored by Andrew Somers and documented in the W3C WCAG 3 explainer, outputs a signed Lc value from roughly negative 108 (white on black) to positive 106 (black on white). The sign encodes polarity. WCAG 2.x is polarity-blind, which is the source of most disagreements.

Where they diverge in practice:

  • Light gray on white at small sizes. WCAG 2.x often passes pairs APCA flags as illegible. #767676 on #FFFFFF is exactly 4.54:1, passing AA, and APCA scores it Lc 53, below the Lc 60 body guideline. APCA is harsher and, in our reading, more correct.
  • Pure black on saturated mid-tones. WCAG 2.x can fail pairs APCA accepts, especially #000000 on saturated yellow or cyan. APCA is more forgiving here because the luminance math weights green heavily.
  • Light text on dark. A 16px regular weight on dark needs Lc 75, not Lc 60, because thin strokes lose contrast in reverse polarity. WCAG 2.x applies 4.5:1 in either direction. If your dark-mode body copy is 4.6:1 you are passing AA and probably failing APCA.

The Lc 60 body floor is a guideline in the APCA Reference Document, not a cutoff in a published Recommendation. Treat it as a decision input, not a certificate.

What failing pairs tell you and how to fix them

A failing ratio is diagnostic. The remedy depends on which channel is dragging it down.

If the foreground is a brand color on white or near-white, darken the foreground in OKLCH or HSL, holding hue constant, until the ratio crosses your threshold. Ratia's auto-fix walks lightness in 1% steps along the same hue family until WCAG crosses 4.5:1, then returns the new hex. #6BA8E8 becomes #1F5EAE at 4.51:1, recognizably the same blue, now passing.

If the foreground is white text on a brand color, darken the background. Lightening white is not an option.

If the pair fails by less than 0.3, suspect font rendering. Light or thin weights at small sizes can fail in production even when the swatch passes, because subpixel rendering chews up effective stroke contrast. Bump weight from 400 to 500 before re-checking.

If the pair fails by more than 3.0, you have a palette problem. The two colors are too close in luminance to ever serve as foreground and background without redesign.

Alpha compositing before you measure

The most common false pass we see is measuring a semi-transparent foreground against its nominal color instead of its composited result. WCAG 2 SC 1.4.3 is unambiguous: contrast is measured against the actual rendered color, which for a translucent layer is the alpha-blend over whatever shows through.

A tooltip with rgba(0, 0, 0, 0.7) over a #F5F5F5 card does not have a black foreground. After compositing it is roughly #494949. The text sits near 7.46:1, not the 18.1:1 that pure black on near-white would imply.

Ratia composites before it measures. When alpha is below 100%, the displayed contrast is the composited result. Drop alpha to 70%, the ratio drops with it, and the AA badge flips if the effective color falls below threshold. The URL permalink encodes alpha alongside the hex values for the same reason: a colleague opening the link must see what you saw.

FAQ

What is the difference between WCAG AA and AAA contrast?

WCAG 2.2 AA requires a contrast ratio of 4.5:1 for normal text and 3:1 for large text (18pt or 14pt bold and above). AAA tightens those thresholds to 7:1 and 4.5:1 respectively. AA is the legal compliance threshold referenced in Section 508, the European Accessibility Act, and most accessibility lawsuits; AAA is aspirational and primarily used on sites with a strong accessibility mission. Ratia shows pass/fail badges for every threshold at once so you can see exactly where a color pair lands without running two separate checks.

What is the APCA Lc value?

Lc (Lightness Contrast) is the output of the Accessible Perceptual Contrast Algorithm, the proposed replacement for WCAG's ratio in WCAG 3.0. It returns a signed value roughly in the range -108 to +106, with negative values indicating light text on dark backgrounds and positive values the reverse. Unlike WCAG's single-threshold ratio, APCA sets different minimum Lc values by font size and weight — body text typically needs Lc 60, while large bold headlines may pass at Lc 30. Ratia computes both WCAG and APCA side-by-side so you can compare the two models on the same color pair.

Does alpha transparency affect contrast calculations?

Yes. Semi-transparent text is visually blended with the background behind it, so the effective color for contrast purposes is the composited pixel, not the raw foreground RGB. WCAG SC 1.4.3 specifies that contrast must be measured on the final rendered output. Ratia performs alpha compositing automatically — if either color has alpha below 100%, it blends the foreground over the background before running the contrast calculation. Most other contrast checkers skip this step, which is why transparent button overlays and glassmorphism elements often silently fail despite appearing to pass.

What contrast do UI components like buttons need?

WCAG 2.2 SC 1.4.11 (Non-text Contrast) requires a 3:1 ratio between adjacent colors for the visual boundaries of UI components — button borders, form input outlines, toggle states, and focus indicators. The text inside a button still needs to meet the 4.5:1 (or 3:1 for large text) threshold. This frequently catches teams out because a subtle border on a tertiary button can pass visual design review while failing WCAG. Ratia's standard checker handles both thresholds; use the 3:1 AA Large badge when you are testing a border against its adjacent fill.

Can I use Ratia offline?

Yes. Every calculation — hex parsing, alpha compositing, WCAG luminance formula, APCA Lc — runs entirely in your browser with no server call. Once the page is loaded and the script bundle is cached, Ratia works without any network connection. The only feature that requires connectivity is permalink sharing, because opening a permalink URL requires a round-trip to load the page (though the actual calculation from URL-encoded colors still happens locally once the page loads).

Why is the European Accessibility Act relevant to contrast?

As of June 28, 2025, the EAA requires that digital products and services sold to consumers in the EU meet accessibility standards — which, for web content, translates to WCAG 2.1 AA compliance including the 4.5:1 and 3:1 contrast thresholds. Non-compliance can trigger fines up to €3 million depending on the member state. Any company with EU customers — including US-based SaaS, e-commerce, and banking — is in scope. Ratia's WCAG 2.2 output covers the contrast portion of compliance, but EAA compliance is broader and includes keyboard navigation, screen reader support, and text alternatives beyond color.

What does the auto-fix suggestion actually change?

Ratia's auto-fix keeps the foreground color's hue and adjusts its lightness (in HSL or OKLCH space) by the smallest amount needed to meet the selected WCAG threshold. It does not touch the background. The output is the nearest-passing color, not an aesthetically optimized one — so a muted brand blue will come back slightly darker or lighter than the original, preserving hue identity while clearing the threshold. The permalink feature encodes the fixed color so you can share the exact passing pair with a designer or PR reviewer.

Ratia is entirely client-side — no colors are sent to any server. Anonymous, consent-gated analytics only. Privacy Policy

Try the Checker