design
WCAG Contrast for SaaS Dashboards: The 5-minute Audit That Catches Most Sins
Most SaaS dashboards quietly fail WCAG contrast on the metrics, sparklines, and disabled states nobody checks. Here's the cheatsheet, the failure patterns, and a 5-minute audit you can run today.
Published 2026-05-31 · 8 min read
Affiliate disclosure
Some links below are affiliate links. I may earn a commission from qualifying purchases at no extra cost to you. I only recommend tools I have used or tested.

TL;DR
- Normal body text needs 4.5:1 contrast (AA); large text needs 3:1.
- UI components, icons, focus rings, and chart elements need 3:1 (SC 1.4.11).
- About three-quarters of SaaS dashboards fail contrast on at least one critical element — usually muted metrics, success-green on white, chart labels, focus rings, or hover-only states.
- Common traps: slate-400 secondary text (3.1:1, fails) and green-500 on white (2.5:1, fails).
- A 5-minute audit (screenshot → contrast checker → OS high-contrast mode → automated linter) catches the obvious failures before customers do.
Your dashboard is probably failing WCAG. Mine was too.
I run a small audit on every SaaS dashboard I see. The pattern is consistent: marketing pages are usually fine. Settings pages are usually fine. The dashboard itself (the part the product actually does) fails WCAG contrast on at least one critical element about three-quarters of the time.
The usual suspects:
- Muted secondary metrics — the small, low-emphasis numbers.
- Chart axis labels — fine lines and tiny text.
- "Ghost" buttons — low-contrast by design.
- Success-green text on white — looks fine, measures terribly.
- The disabled state of the primary button.
These are exactly the elements designers iterate on most, and exactly the elements that get tweaked away from the safe brand palette during sprint pressure.
This post covers the 5-minute audit I run, the four contrast rules worth memorizing, and the tools (including a free contrast ratio checker) that catch the failures before a customer files an accessibility complaint.
The contrast rules, distilled
The W3C's Web Content Accessibility Guidelines define two contrast levels for text. After years of debugging real dashboards, I've reduced them to a single table that lives on a sticky note next to my monitor:
| Text type | AA (minimum) | AAA (preferred) |
|---|---|---|
| Body text (under 18pt regular or 14pt bold) | 4.5:1 | 7:1 |
| Large text (18pt+ regular or 14pt+ bold) | 3:1 | 4.5:1 |
| UI components + graphical objects (icons, focus rings, chart elements) | 3:1 | — |
These are from WCAG 2.1 Success Criterion 1.4.3 (Contrast Minimum) and 1.4.11 (Non-text Contrast). They're not negotiable for legal compliance in most jurisdictions, and they line up surprisingly well with what feels readable.
Two practical implications most teams miss:
-
Sparklines and chart strokes are UI components, not text. They fall under the 3:1 rule, but
#cbd5e1(slate-300) on white is 1.65:1. Most dashboard charts I see fail this and nobody is enforcing it. -
Disabled states are exempt from contrast requirements under SC 1.4.3, but only if they're genuinely non-interactive. If a "disabled" button still triggers a tooltip or shows an error on click, it's interactive, and the rules apply.
The 5 patterns that fail in every dashboard I audit
After auditing dozens of SaaS UIs, these are the same five failures over and over:
1. Muted secondary metrics. "Last updated 2 hours ago" in #94a3b8 (slate-400) on a #f8fafc background. That's 3.1:1, which fails AA for body text. The fix is one shade darker (slate-500 is 4.6:1). Designers default to slate-400 because it "looks elegant"; it's also illegal.
2. Success/danger text on white. #22c55e (Tailwind green-500) on white is 2.5:1. Catastrophic failure. Use green-700 (#15803d) at 4.7:1 minimum. This trips up almost every dashboard that uses a default color framework without tuning.
3. Chart axis labels. Lines and small text in #94a3b8 fail. Charts need at least slate-500 (4.6:1) for labels and ≥ 3:1 contrast for the lines themselves.
4. Focus rings. The trendy "no focus ring" reset breaks 2.4.7 (Focus Visible) entirely. If you've removed the default focus ring, you need a custom one with ≥ 3:1 contrast against the background. The A11y Project has a thorough guide on focus visibility that's worth reading once.
5. Hover-only contrast. A button that fails contrast at rest but passes on hover doesn't meet the criterion. The rest state is what gets audited.
The 5-minute audit
This is the workflow I run on any dashboard before shipping a redesign. Five steps, five minutes:
1. Open the page in question. Pick the busiest screen, not the empty state.
2. Take a screenshot. Drag it into a contrast checker. For each color pair you're worried about, sample the pixel values and check the ratio.
3. Generate a candidate "safe" palette using a color palette generator. Even if you don't use the output, the contrast ratios it shows for each pair are a quick sanity check against your current palette.
4. Test with the OS-level "Increase contrast" accessibility setting on (macOS: System Settings → Accessibility → Display). About 8% of users have this turned on. If your "subtle" elements disappear entirely, you have a problem.
5. Run the page through an automated linter (Axe DevTools, Lighthouse, WAVE). These catch maybe 30-40% of issues but they catch the ones you'd be most embarrassed about.
This audit is not a substitute for hiring an accessibility consultant for a real product. It is enough to catch the obvious failures that ship every Friday afternoon.
Where automated tools miss things
Three failure modes automated checkers do not catch:
- Data-dependent contrast. If your "low" state is gray-300 and "high" is red-600, the contrast between them is fine. The contrast of each individually against the background still needs to be ≥ 3:1, and a checker won't know that "low" can occur on its own.
- Composite contrast. Stacked translucent overlays (the modern glassmorphism look) shift contrast based on what's behind them. Static checkers see only the foreground color.
- State changes that change context. A status pill that turns from gray to amber doesn't change in contrast against the background; it changes in meaning. Color-blind users may miss the change entirely. The Smashing Magazine guide on dashboard accessibility patterns covers this kind of multi-channel signaling well.
The fix for all three is the same: pair every color signal with a non-color cue (icon, label, weight). Belt and suspenders.
A pragmatic palette
If you want a starting point that nearly always passes AA when used correctly:
- Body text: slate-700 (
#334155) on slate-50 (#f8fafc) = 10.8:1 - Secondary text: slate-500 (
#64748b) = 5.3:1 (passes AA body, fails AAA) - Accent on white: anything in the 600 weight range of the major frameworks
- Success: green-700 (
#15803d) = 4.7:1 - Danger: red-700 (
#b91c1c) = 6.0:1
Run any custom values through a color contrast checker before you ship. Two minutes saved arguing with a designer is worth two hours not spent re-tuning the palette after a customer files an a11y complaint.
The mindset shift
Most contrast failures aren't designers ignoring accessibility. They're designers chasing "elegance" and not realizing the elegant choice is also the illegible one. The fix is to put a contrast check next to every color decision in the design system, not at the end as a compliance step.
If you do nothing else from this post: open your current dashboard, pull up a color contrast checker, and check the three most muted text colors. You will almost certainly find at least one failure. Spend the 10 minutes to fix it before the next design review. It is the single highest-ROI accessibility task on the board.
Bottom line: Memorize the three ratios (4.5:1 body, 3:1 large text, 3:1 UI/charts) and check contrast next to every color decision, not as a last-minute compliance step. Five minutes today saves a customer accessibility complaint later.
Don't forget the focus ring
Contrast isn't only about text and icons — it's also about the focus indicator that shows which control a keyboard user has landed on. WCAG 2.4.7 (Focus Visible, level AA) requires that indicator to be perceivable, and a faint one-pixel outline that vanishes against a colored button fails the people who navigate without a mouse. The most common version of this mistake is removing the browser's default outline for "cleanliness." Don't: keep a visible focus style with real contrast against both the component and the page, and check the focus state of every interactive element, not just its resting and hover colors.
Sources
- W3C: WCAG 2.1 Success Criterion 1.4.3: Contrast (Minimum)
- The A11y Project: Never remove CSS outlines
- Smashing Magazine: Accessibility best practices for tabs and dashboards





