Software & Apps

How to Check Button Text Contrast Before Launch

A practical pre-launch check for button labels: test your text colour against the fill, fix the pairs that fail WCAG, and review hover and disabled states.

A button label is usually the smallest text doing the biggest job on a page. It is often 14 to 16 pixels tall, and it is the text a visitor must read to take the next step. When that label is hard to read, the button still looks like a button — visitors simply hesitate or leave. Checking button text contrast before launch takes about a minute per button. This guide shows how to test the actual text colour against the actual fill colour, with a worked example on orange, green and grey fills, and how to review the hover and disabled states most teams forget — using FBSubNet's free Two-Color Contrast Checker.

Button contrast problems

Most button contrast failures come from one habit: the fill colour is chosen as a swatch, and the text colour is assumed. A designer picks a friendly orange or a fresh green, drops white text on top because that is the convention, and moves on. But white text is only a safe default on dark fills. On a mid-tone fill — bright orange, medium green, cheerful yellow — white sits close to the fill in brightness, and the gap is too small to read comfortably.

The numbers explain why. WCAG measures readability as a contrast ratio between two colours, from 1:1 (identical, invisible) to 21:1 (pure black on pure white), and Level AA requires at least 4.5:1 for normal text. Button labels are almost always normal text — smaller than 24 pixels, and below the bold 18.66-pixel threshold for large text — so the bar for a button label is 4.5:1. White text on a medium green can measure around 3.5:1; white on a bright orange around 3.6:1. Both look fine in a mockup, and both fail the standard.

Three other habits cause button failures. The first is testing only the primary button: a page usually has several styles, and the secondary ones hide the failures, because they use lighter fills or coloured text on a white page. The second is forgetting that a button is more than its label: under Success Criterion 1.4.11, non-text contrast, the button's boundary also needs 3:1 against its surroundings, so a pale outline button can fail even when its label passes. The third is judging by eye. Contrast is a luminance calculation, not a design opinion, and the boundary between pass and fail is often a single shade. The only reliable way to know is to measure the exact pair.

Colour vision is another reason to measure rather than guess. Around one in twelve men and one in two hundred women have some form of colour vision deficiency, and the most common kinds make reds and greens hard to tell apart — so a green success button and a red danger button that differ only in hue can look identical to those readers. A destructive action needs a clear label or icon as well as a red fill. See our guide to WCAG contrast ratios for normal and large text for the background on the thresholds.

Check text on fill

The check is simple; the discipline is testing the real pair rather than a remembered one. Open the Two-Color Contrast Checker, enter the exact foreground colour — the HEX value of the label text as it ships — and the exact background colour, the HEX value of the button fill. Read the ratio and compare it with the threshold for the label's size: 4.5:1 for normal text, 3:1 if the label genuinely qualifies as large text. On a gradient or photograph, test the lightest part of the background behind the text — that is where the ratio is worst.

The worked example below uses three fills from real products: a bright orange, a medium green and a mid grey. Each is tested with white text and near-black text, using the WCAG relative-luminance formula — the same calculation the checker performs. You can reproduce every number by entering the same pair into the checker.

Orange fill #E8590C

White text (#FFFFFF) on this orange measures 3.58:1. That passes the 3:1 large-text threshold, but a button label is normal text, so it fails the 4.5:1 requirement by almost a full point. Near-black text (#1A1A1A) on the same fill measures 4.86:1, which passes AA for normal text. The fix costs nothing visually: keep the orange, change the label to a dark colour. This is the pattern with most warm mid-tones: the gap between white and a bright orange is smaller than the gap between that orange and a dark ink.

Green fill #2F9E44

White text on this green measures 3.45:1 — a fail for normal text, and a worse one than the orange. Near-black text on the same green measures 5.05:1, a comfortable pass with half a point of margin. Green is the fill that catches the most teams: it means success, confirmation, go. A green button with white text feels correct — it is the default in several popular component libraries — but the default is a design choice, not a measurement, and this green is simply too light for white lettering. If the brand green cannot change, the label colour can.

Grey fill #6C757D

White text on this mid grey measures 4.69:1, which passes AA for normal text — but only just, with 0.19 of margin. A pass by 0.19 on a desktop monitor can fail on a cheap laptop in bright daylight, so treat this as a pass with a warning attached. It also shows how narrow the boundary is: one shade lighter and the same white text would fail.

When a pair fails, change one colour at a time and keep the hue. Darken the fill until the ratio clears 4.5:1 with a margin of at least 0.5 — aim for 5:1 or better, not a photo finish at 4.51:1 — or switch the text colour, as in the orange and green examples above. Nudging the fill by a single shade does not solve the problem. A passing ratio is a floor, not a guarantee: a 4.5:1 pair in a thin typeface at 12 pixels is technically compliant and still hard to read.

Review hover and disabled states

A button that passes at rest can fail the moment a visitor interacts with it, because hover, focus and active states change the colours. The most common hover treatment is to darken the fill slightly, which usually helps white text — a darker background increases the gap to white. But the three fills above show why each hover state needs its own test.

Darken the orange fill to #D9480F for hover and white text measures 4.30:1 — better than the resting 3.58:1, but still a fail. Darken the green fill to #2B8A3E and white text measures 4.37:1 — again improved, again a fail. Only the grey fill behaves: darkening it to #5C636A for hover takes white text to 6.09:1, a comfortable pass. A single-step darkening of a failing fill is rarely enough: if the resting pair fails, the hover pair built from the same colours will usually fail too, just by less. Fix the resting pair first, then re-test the hover pair.

Hover has a second trap: some designs lighten the fill on hover, or swap a solid fill for an outline, and both moves reduce contrast. A hover state that inverts the button needs the same measurement as a new button. And hover is not the only state — the focus indicator, the visible ring that shows keyboard users where they are, needs 3:1 contrast against its adjacent colours under the non-text contrast rule. A faint blue ring on a blue button can be invisible to the people who need it most, even when the label is perfect. Test the focus ring against the page background and the button fill, and make it thick enough to see at a glance.

Disabled states are the exception that proves the rule. WCAG explicitly exempts inactive controls from the contrast requirements, so a greyed-out submit button does not need to reach 4.5:1. That is not permission to make disabled buttons unreadable, though: the button must still be recognisable, and its label legible enough to tell what action is unavailable. Keep the label at the same size, use a muted but readable grey, and do not rely on colour alone — pair the faded fill with reduced opacity and a short explanation nearby of what would enable the button. A disabled button is also not focusable, so a keyboard user cannot reach it to discover why; the explanation belongs in visible text near the button, not in a hover-only tooltip.

A pre-launch button contrast checklist

Run through this list for every button style on the page, not just the primary action. First, list every variant: primary, secondary, danger, success, ghost or outline, and any text-only button that looks like a link. Second, measure the resting label pair for each variant and confirm 4.5:1 for normal text or 3:1 for genuinely large text. Third, measure the hover and active pairs, and confirm the focus indicator reaches 3:1 against both the button and the page. Fourth, check the disabled state: exempt from the ratio, but the label should still be readable and the state clear without colour alone. Fifth, look at the button in context — on the real page background, at the real size, on a real phone outdoors if your visitors will use one. A pair that passes in a checker can still struggle on a dim screen in sunlight, so keep a margin above the minimum rather than shipping a 4.51:1 pass.

Finally, record what you tested — fill, text colour, ratio, pass or fail — and re-test after every design change, so the check happens before launch instead of after a complaint.

Frequently asked questions

Is white text on a coloured button always a problem?

No. White text is fine on a dark enough fill: white on a deep blue such as #1B6EC2 measures 5.18:1. The problem is mid-tone fills, where white sits too close to the fill in brightness — measure the exact pair instead of trusting the convention.

Can I use a 3:1 ratio for button labels?

Only if the label qualifies as large text under WCAG: 24 pixels or bigger at regular weight, or 18.66 pixels and up when bold. Most button labels are 14 to 16 pixels, so they are normal text and need 4.5:1 — and fixing the colours is usually simpler than making the label bigger.

Do disabled buttons need to pass contrast checks?

No. WCAG exempts inactive controls from the contrast requirements. Keep the label readable anyway, make the disabled state obvious without relying on colour alone, and put the reason in visible text nearby, since keyboard users cannot focus a disabled button to discover it.

Does a passing contrast ratio mean the button is accessible?

No. Contrast answers one question about two colours. A button also needs a clear label, a visible focus indicator, keyboard access, and meaning that does not depend on colour alone. Use the checker as a fast gate before launch, then check the rest the same way.

The short version

Button labels are normal text, so they need at least 4.5:1 at WCAG Level AA. Measure the exact text colour against the exact fill colour, and do not assume white text is safe: white on orange #E8590C measures 3.58:1 and white on green #2F9E44 measures 3.45:1, while dark text on the same fills passes at 4.86:1 and 5.05:1. Test the hover state separately — darkening a failing fill by one step often still fails — and check the focus indicator against 3:1. Disabled buttons are exempt, but their labels should stay readable and the state should not depend on colour alone. A minute per button, before launch, is all it takes.