Back to Blog

WCAG Contrast for Buttons and Links: Hex Examples for Web UI

9 min read

Links and buttons are how people complete tasks on the web. If the label color is too close to the background, WCAG audits fail and real users miss CTAs. This article walks through accessible button and link colors with hex swatches placed next to each idea—so you see examples as you read, not after a long theory section. Use our contrast checker to verify every pair, and our palette generator when you need related hover and active shades.

Quick kit (copy any hex into the contrast checker):

White page

Warm off-white

Cool off-white

Body

Link

Primary btn

Start with the page background, then the control

Contrast is always two colors at a time: link blue on the paragraph background, or white label text on the button fill. A palette that looks “on brand” in a style tile can still fail once it sits on a gray card or a tinted hero. Name your layers (page, card, button) and test the combination you actually ship.

Below is a typical white page with near-black body copy. That body color is a safe default for paragraphs; your link color must also clear 4.5:1 on the same white (for normal-sized link text).

Page

Body text

If your marketing site uses an off-white shell, swap #ffffff for your real surface hex before signing off on link colors.

Common marketing shells—test links and buttons on the exact value you ship:

Warm shell

Cool shell

Stone shell

Link colors: why light blue often fails

Pastel blues are popular for links but frequently fall under 4.5:1 on white at 14–16px. A darker blue usually fixes compliance without killing the “clickable” feel—especially if you keep an underline for default links.

Swatches: a risky light link blue vs a safer link blue—confirm in the checker for your exact font size and weight.

Risky link (test)

Safer link blue

Other link styles—still compare against your page or card background:

Success / go link

Visited purple

Warning tone link

If you must keep a lighter blue, use it only for large text (18pt+ regular or 14pt+ bold) where 3:1 applies, or darken one step for inline links. Our WCAG contrast guide explains the AA thresholds in more detail.

Filled primary buttons on a light page

For a solid primary CTA, check label on fill first. White on a strong blue is a common pattern; tweak saturation until the ratio passes for your type size.

Button fill

Label

Alternate brand primaries—same rule: label-on-fill must pass for your type size.

Emerald fill

Label on emerald

Violet fill

Label on violet

Orange fill

Label on orange

When the same blue is used as a text link on white (no fill), it must pass as text on white—often a different shade than the one you use behind white button labels. Maintain two tokens if needed: link.default and button.primary.fill.

Outline and secondary buttons on gray surfaces

Secondary actions often sit on subtle gray panels. The border, label, and panel each form pairs: label vs panel, border vs panel, and sometimes label vs page if the button is visually “open.”

Card / panel

Border

Label

Destructive and low-emphasis variants—check border vs panel and label vs panel:

Soft danger bg

Danger border

Danger label

Ghost surface

Ghost border

Ghost label

If the border is too light, users with low vision lose the button shape—bump contrast on the stroke before you lighten the text. Ghost buttons on busy imagery need extra care; prefer a semi-opaque scrim or a solid chip behind the label.

CTAs on tinted bands and footers

Hero sections and footers often use mid-tone backgrounds. A white button can pass on a navy band; a cyan text link might not. Pick one primary action style and test it on the band hex, not only on white above the fold.

Dark band

Solid button

Label on white btn

Alternative: keep the band dark and use a high-chroma fill with a light label—again, verify label-on-fill and any secondary link on the same band.

Accent fill

Label on accent

Text links sitting on the same navy band (no button fill)—light cyan often fails small sizes; compare:

Band (again)

Risky inline link

Safer link on dark

Hover, active, and focus-visible

Hover states that only change hue slightly can drop below passing contrast. Darken the fill a step or lighten the text—then re-run the checker. For keyboard users, focus rings must stand out from both the component and whatever is behind it.

Hover fill (darker)

Active / pressed

Focus ring

Disabled buttons—label vs fill (or label vs panel for ghost) usually needs a deliberate gray, not just low opacity:

Disabled fill

Disabled label

Disabled on panel

Muted label

If you use box-shadow for focus, sample the ring color against the underlying page and button colors. Transparent hovers need flattened RGB values before testing.

Reference strip (save for audits)

Handy hex set to paste into our tools—mix and match only after each pair passes:

Page

Panel

Ink

Link

Primary

Band

On-dark btn

Focus

Short workflow

  1. List every background your links and buttons appear on.
  2. For each control state, note foreground and background hex codes.
  3. Run pairs through the contrast checker.
  4. Adjust fills or type weight; use the palette generator for harmonious alternates.

Frequently Asked Questions

What contrast ratio do links need for WCAG AA?

Normal link text typically needs 4.5:1 against its background; large link text needs 3:1. Verify with your exact hex values and font size.

Do buttons use the same rules as body text?

Button labels are text, so label versus button background should meet the appropriate text contrast level. Borders and icons may need separate checks under UI component guidance.

Can I use a light blue for links on white?

Often no, for small text—test first. Prefer a darker blue, larger weight, or both, and keep underlines where possible.

What besides default states should I test?

Hover, active, disabled, and focus-visible. Flatten any transparent colors before measuring.

Try our free tools

Click above to use our tools — no account required

Share this article

Ad Space (728x90)