How to Fix WCAG Contrast Fail in Figma
Fixing a failing contrast ratio doesn't mean destroying your brand colors. Learn how to fix WCAG AA and AAA failures mathematically in Figma with minimal perceptual shift.
The Problem: The Dreaded "Contrast Fail" in Figma
You’ve crafted an elegant, balanced UI in Figma. The typography is balanced, the card borders are crisp, and the secondary text sits in a refined subtle slate.
Then, you run an accessibility audit. Red warning badges light up across your screen:
Most designers react in one of two ways:
- The Blind Drag: They open the Figma color picker and drag the brightness slider down until the ratio turns green. The text is now compliant, but it looks heavy, muddy, and competes with the primary headline.
- The Size Hack: They make the text 24px or bold just to qualify for the looser 3.0:1 "large text" threshold, destroying their design system’s typographic hierarchy.
There is a vastly better way. In this tutorial, we will walk through how to resolve WCAG contrast failures mathematically using perceptually uniform color adjustments.
Step 1: Understand the Exact WCAG Threshold Required
Before changing a single pixel, make sure you are targeting the correct threshold according to WCAG 2.1 Success Criterion 1.4.3 (Contrast Minimum):
- Normal Text (< 24px, or < 18.66px bold): Requires a minimum contrast ratio of 4.5:1 for Level AA compliance (7.0:1 for Level AAA).
- Large Text (≥ 24px regular, or ≥ 18.66px bold): Requires a minimum contrast ratio of 3.0:1 for Level AA (4.5:1 for Level AAA).
- UI Components & Graphical Objects (SC 1.4.11): Form input borders, active toggles, and icons require 3.0:1 against adjacent colors.
Note on font weight: In CSS and Figma, 14pt bold corresponds to 18.66px with font weight 700. If your text is 19px medium (weight 500), it still requires 4.5:1!
Step 2: Why Standard Color Pickers Distort Your Palette
When you adjust colors using standard RGB or HSL sliders, you are working in a color space that does not reflect human vision.
Human eyes are significantly more sensitive to green wavelengths than to blue wavelengths. In standard sRGB:
- Changing green by 10% drastically alters perceived lightness.
- Changing blue by 10% barely looks different to human eyes.
- In HSL, maintaining a constant "Lightness" value across different hues results in wildly different WCAG luminance values.
This is why dragging the slider manually turns refined grays into muddy purples or sickly greenish tones. To preserve brand integrity, color adjustments must be calculated in OKLab (created by color scientist Björn Ottosson), where Euclidean geometric distance corresponds directly to perceived color difference:
Step 3: Finding the Minimum Compliant Shift with Smart Fix
Instead of guessing which hex code will pass, TintSense’s Smart Fix engine calculates candidate colors directly:
- It translates your original failing hex color and background color into linear relative luminance.
- It projects the color into OKLab space, locking the chroma and hue coordinates (
aandb) to preserve the exact chromatic character of your brand. - It optimizes the lightness parameter (
L) with binary search until the contrast ratio reaches4.52:1(including a +0.02 safety margin for browser subpixel anti-aliasing). - It returns the candidate with the smallest perceptual distance ($\Delta E$).
Step 4: Fixing Failures in Figma (The 10-Second Workflow)
Here is how to remediate an entire failing artboard in Figma using TintSense:
- Select your target frame or component: Select any frame or multiple frames on the canvas.
- Run TintSense: Press ⌘/ in Figma, type
TintSense, and hit Enter. - Review the failing layers: In the TintSense panel, frames with contrast issues display red badges with the failing text count. Click into the frame to view individual failing rows.
- Option A — Apply individually: Review the suggested color swatch under any row and click Apply. The layer’s fill immediately updates in Figma.
- Option B — Batch "Fix All": Click Fix All in the top header. Every failing text layer on the screen will update to its optimal OKLab compliant shade in less than one second.
- Undo anytime: Full undo (⌘Z) is preserved if you want to revert or compare states.
Step 5: Updating Design System Variables & Tokens
If your failing layer is bound to a Figma Color Variable (e.g. color/text/muted), updating the layer directly might detach the variable or create inconsistency across other screens (see our complete architecture tutorial on accessible color palettes in Figma Variables).
Best Practice:
- When TintSense suggests
#627284as the compliant alternative for your secondary text token, navigate to your Figma Variables panel. - Edit the value of
color/text/mutedto the new compliant hex code. - Because TintSense’s OKLab fix preserves exact hue and chroma, the change will look seamlessly natural across all your light and dark modes while instantly bringing every component into full compliance!
Quick Checklist: Avoiding Future Contrast Failures
- ✓ Keep a minimum 4.5:1 ratio for any text under 24px (and 3.0:1 for large text).
- ✓ Beware of semi-transparent card fills (read our deep dive on why contrast checkers fail on transparent cards).
- ✓ Test text over imagery and gradients using TintSense’s gradient analysis.
- ✓ Turn on Canvas HUD Badges in TintSense so you see live contrast ratios while designing, before handing off to development.
- ✓ Prepare for compliance mandates like the European Accessibility Act (EAA) during design sprints.
Never fail a contrast audit again
Install TintSense in Figma for free. Scan entire frames, see live canvas badges, and fix failing colors with 1 click.