Accessible Link Colors: Getting 4.5:1 Without Ugly Blue
The default browser link blue, #0000EE, measures 9.4:1 on white. It comfortably passes every WCAG threshold, and almost no design system uses it, because it reads as an unstyled document from 1996. Replacing it is where accessibility problems start: most brand-friendly blues sit somewhere between 2.5:1 and 4:1 on white, and once a designer removes the underline as well, the link has quietly stopped being identifiable as a link for a meaningful share of users.
This post is about that specific decision — what link colors actually have to satisfy, why the color-only route is mathematically much tighter than it looks, and which combinations genuinely work. For contrast fundamentals and the luminance math behind the ratios, see The Complete Guide to Accessible Color and Contrast.
Two requirements, not one
A link inside body copy has to clear two separate bars.
1. Contrast against the background — 4.5:1. Links are text, so 1.4.3 Contrast (Minimum), Level AA applies exactly as it does to body copy: 4.5:1 at normal size, 3:1 if the link text is large (18pt/24px, or 14pt/18.66px bold). Nothing about being a link changes this. WCAG Contrast Ratios Explained: AA vs AAA covers the thresholds in detail.
2. Distinguishable from surrounding text without relying on color. This is 1.4.1 Use of Color, Level A. If the only thing separating the link from the paragraph around it is hue, the link is invisible as a link to a user with color vision deficiency, and it fails at the minimum conformance level.
There are exactly two ways to satisfy the second requirement:
- Underline the link. Done. A non-color visual distinction exists.
- Use the color-only route defined in WCAG technique G183: make the link at least 3:1 against the surrounding text color, and provide a non-color distinction — typically an underline — on hover and focus.
Worth being precise about that 3:1 number, because it is widely misquoted. It comes from technique G183, which is a sufficient technique for 1.4.1, not from the text of a success criterion. Separately, 1.4.11 Non-text Contrast (Level AA) requires 3:1 for your focus indicator against adjacent colors — a different obligation that applies to every link regardless of which route you take.
Why the color-only route is so tight
Run the two constraints together and the available color space collapses.
Suppose body text is #1A1A1A — a common near-black, 17.4:1 on white. The link color has to be:
- light enough that it sits 3:1 away from that near-black text, and
- dark enough that it keeps 4.5:1 against the white background.
Those pull in opposite directions. Working the luminance formula through, the surviving window is a link color measuring roughly 4.5:1 to 5.8:1 on white. That is it — a band about one and a quarter ratio points wide.
Now make body text #333333 instead, at 12.6:1 on white. The window closes entirely. The lightest color that still holds 4.5:1 on white reaches only about 2.8:1 against #333333, short of the 3:1 requirement. With #333 body text, no color-only link is conformant. Not "hard to find" — arithmetically impossible.
That result is worth internalising, because #333 body text with unstyled colored links is one of the most common patterns on the web, and it cannot be fixed by picking a better blue.
Link colors that actually work
Assuming near-black #1A1A1A body text on white, these sit inside the window — 4.5:1 or better on white and 3:1 or better against the text:
| Color | On white | vs #1A1A1A text |
Notes |
|---|---|---|---|
#0F62FE |
5.00:1 | 3.48:1 | Vivid blue, comfortable margin on both |
#2563EB |
5.17:1 | 3.37:1 | Common Tailwind-family blue |
#0B5FFF |
5.13:1 | 3.39:1 | Saturated, modern |
#0066CC |
5.57:1 | 3.13:1 | Calmer, near the edge of the window |
#0F766E |
5.47:1 | 3.18:1 | Teal, useful when blue is taken by brand |
#7C3AED |
5.70:1 | 3.05:1 | Purple; only just clears 3:1 |
And the near-misses that make the point — perfectly good link colors that require an underline:
| Color | On white | vs #1A1A1A text |
Why it fails color-only |
|---|---|---|---|
#1750B5 |
7.37:1 | 2.36:1 | Too dark; merges with body text |
#1A56DB |
6.18:1 | 2.82:1 | Just outside the window |
#B91C1C |
6.47:1 | 2.69:1 | Too dark, and red is a poor CVD choice |
#0000EE |
9.40:1 | 1.85:1 | The browser default — fine, but underlined for a reason |
Note the pattern: the better a color's contrast against the background, the worse its separation from dark body text. Darkening a link to make it "more accessible" actively breaks the color-only route.
Verify any candidate of your own in the Contrast Ratio Checker (WCAG AA/AAA) — check it twice, once against your background and once against your body text color. If your brand color misses, feed it to the Accessible Color Pair Finder to get the nearest variants that clear a chosen threshold, and use the Color Shade Generator to build a matching ramp for hover, visited, and dark-mode variants. Everything runs client-side, so an unreleased palette never leaves the browser.
Dark mode is tighter still
The same two constraints apply, and the window shrinks. Against a #121212 background with #E6E6E6 body text (15:1), a color-only link has to land between roughly 4.5:1 and 5.0:1 against the background — half a ratio point of room.
#2F80ED fits: 4.85:1 on #121212, 3.10:1 against #E6E6E6. The popular pale dark-mode blues do not — #8AB4F8 measures 8.89:1 on the background but only 1.69:1 against the body text, so a dark theme using it must underline.
The practical conclusion for dark themes: underline, and stop tuning.
Hover, focus, and visited
Hover. If you took the color-only route, the underline on hover is not optional — G183 requires it. Also check the hover color independently: darkening #0F62FE to #0043CE gives 7.79:1 on white, which is fine, but a lightening hover state frequently drops below 4.5:1.
Focus. Every link needs a visible focus indicator meeting 3:1 against adjacent colors under 1.4.11. Do not remove the default outline without replacing it. outline: 2px solid in a color you have measured, with outline-offset: 2px, is the standard.
Visited. WCAG does not require a distinct visited state, but it remains genuinely useful on reference-heavy sites. If you style one, it is text too — the visited color needs its own 4.5:1. Classic #551A8B gives 11:1 on white; a modern #6D28D9 gives 7.10:1.
Underline styling. Underlines are free to be tasteful. text-underline-offset: 0.15em and text-decoration-thickness: 1px with text-decoration-skip-ink: auto produce an underline that clears descenders and reads as deliberate rather than default. A border-bottom works too, but skip-ink does not apply to it.
A recommendation
Underline links in body copy. It costs one CSS declaration, it satisfies 1.4.1 unconditionally, it frees your link color to be any hue that clears 4.5:1 against the background, and it survives every design change downstream — a body-text token nudge from #1A1A1A to #333 silently breaks a color-only implementation and does nothing to an underlined one.
Take the color-only route only when you control both the link and body-text tokens, you have verified both ratios, and you are shipping the hover and focus underlines with it. If you inherit a site full of unstyled colored links, How to Fix Failing Color Contrast on Your Site covers the token-level repair process that keeps the fix from regressing.
Frequently asked questions
What contrast ratio do link colors need?
At least 4.5:1 against the page background, the same as any normal-size text under WCAG 1.4.3 Level AA. If the link is inside body text and has no underline, it additionally needs at least 3:1 against the surrounding text color, plus a non-color distinction on hover and focus.
Do links have to be underlined to be accessible?
Not strictly. WCAG 1.4.1 Use of Color requires a non-color distinction, and an underline is the simplest one. The accepted alternative, described in WCAG technique G183, is 3:1 contrast against the surrounding text plus an underline (or equivalent) on hover and focus.
Where does the 3:1 link contrast figure come from?
From WCAG technique G183, a sufficient technique for satisfying 1.4.1 Use of Color. It is a technique rather than a numeric criterion, which is why the 3:1 figure does not appear in the text of any success criterion itself.
Why is it so hard to find a link color that is 3:1 from body text?
The two requirements pull in opposite directions. The link must be light enough to sit 3:1 away from near-black body text, and dark enough to keep 4.5:1 against a white background. That leaves a window roughly between 4.5:1 and 5.8:1 on white, and only if body text is very dark.
Can I use color-only links with #333 body text?
No. With body text at #333333 (12.6:1 on white), no color exists that is simultaneously 3:1 from the text and 4.5:1 on white. The best achievable is about 2.8:1 against the text. Either darken body text toward #1A1A1A or underline the links.
Do visited links need to look different?
WCAG does not require a distinct visited state, but it is a long-standing usability convention and helps users navigating large reference sites. If you style one, the visited color must independently meet 4.5:1 against the background.
What about links in dark mode?
The same thresholds apply, but the window is even narrower. Against a #121212 background with #E6E6E6 body text, a color-only link has to land between roughly 4.5:1 and 5.0:1 on the background. Underlining is the practical answer in dark themes.
Try the related tools
Contrast Ratio Checker (WCAG AA/AAA)
Check WCAG contrast ratio between text and background colors for accessibility compliance.
Color Shade Generator
Generate darker shades of any base color with configurable steps.
Accessible Color Pair Finder
Find the closest accessible text color (black, white, or adjusted hue) meeting WCAG AA.
Related articles
The Complete Guide to Accessible Color and Contrast
A complete guide to accessible color: WCAG 2.1 contrast ratios, how contrast is calculated, color blindness types, and practical fixes for failing palettes.
WCAG Contrast Ratios Explained: AA vs AAA
What the WCAG contrast ratio numbers mean, how 4.5:1 and 7:1 were chosen, when large text qualifies for 3:1, and how to decide whether you need AA or AAA.
How to Fix Failing Color Contrast on Your Site
A step-by-step process to fix color contrast failures without wrecking your brand palette: triage by impact, shift lightness not hue, and repair tokens at the source.