Fix contrast errors on primary call-to-action buttons

A Get a quote button in white on a pale brand fill can pass a screenshot review and still fail contrast. Measure the label against the fill, then check hover, focus, and overlays.

5 min read Hammad Sheikh
Website UX & Design
5 min read Hammad Sheikh

The primary button says Get a quote in white on a pale brand fill. On a calibrated monitor it looks on-brand. On a phone in daylight the label disappears.

Sales reports bounce before the form. Buyers never found the control they were asked to press.

This post is how to find and fix that contrast. It is not a test of the words on the button.

Measure the label against the fill

Web Content Accessibility Guidelines (WCAG) Success Criterion 1.4.3 requires a contrast ratio of at least 4.5:1 between text and its background. That background is the button fill, not the white page behind the button.

A brand chip that passes 4.5:1 on white can still fail once you put white type on that same chip. The pair that matters is label versus fill. Understanding Contrast (Minimum) is the source for the ratio, the large-text exception, and what is exempt.

Most primary buttons use 16 pixel type, even when the weight is bold. That is regular text, so 4.5:1 applies. The 3:1 large-text bar starts at 24 pixels, or about 18.5 pixels when the type is bold.

Do not round a 4.499:1 sample into a pass. WCAG treats 4.5:1 as a threshold, not a number you pad. Sample the computed colors from the stylesheet, not a screenshot that anti-aliasing has already lightened.

The logo exception does not save this control. WCAG exempts text that is part of a logo or brand name.

It does not exempt the rest of the brand book. A Get a quote fill is a user interface control, not a logotype.

Inactive controls are also exempt. A disabled submit that waits on required fields does not have to meet 1.4.3.

A live primary button that looks washed-out because the brand is pale is not inactive. Style the live state to pass.

These are the failures that show up on B2B headers and heroes. Each one is a pair you can measure, not a taste debate.

  • White label on a pastel brand fill that only passed when sampled on the page.
  • Grey label on white, used as the primary action because the brand fill felt loud.
  • An image-of-text button exported from a slide, with no way to restyle the pair.
  • Placeholder copy inside the button treated as the label, then ignored in the audit.
  • A Choose plan control that still fails after a pricing table overflow fix.

Check the states people actually use

Contrast has to hold when someone hovers, tabs, or lands the button on a photo. WCAG 1.4.3 applies to hover text and to text shown on focus, not only to the default swatch in Figma.

Hover and focus

A hover that lightens the fill often drops a passing 4.6:1 label into a fail. Keep the label readable in the hover fill, or darken the fill on hover instead of bleaching it.

Focus is a different pair. Understanding Non-text Contrast requires a 3:1 ratio for visual information that identifies a control and its states, against adjacent color.

If you draw a focus ring, that ring must contrast with the surface it sits on. A pale yellow outline on white fails 3:1 even when the label inside the button still passes 4.5:1.

Do not rely on a fill-color change alone to show focus. Hue shift without a luminance change also fails Use of Color.

Hover effects you add on top of a native button are supplemental. They do not have to contrast 3:1 as a hover badge. They must not make the control or its focus mark drop below the ratios above.

Ghost buttons and hero overlays

A transparent primary with a 1-pixel brand border is two checks. The label still needs 4.5:1 against whatever shows through the button, including a busy hero image. The border, if it is the only way to see that a control is there, needs 3:1 against adjacent color.

If the label is already visible, WCAG does not require a hit-area outline. Low-vision buyers still miss a faint ghost on a photograph. Prefer a solid fill that passes 4.5:1 over a see-through primary that only works on a studio background.

Putting Get a quote as a raster on the hero is an image of text. It still has to meet 1.4.3, and you cannot restyle it when the photo changes. Use real text on a fill you control.

Fix the pair, then re-check adjacent color

Darken the fill or darken the label until the default state clears 4.5:1. Then repeat the measure on hover and on the actual page background, including dark sections and photos.

If the control is only findable because of a border or icon, run the 3:1 non-text check against adjacent color. A filled button whose text already identifies it can skip a decorative border. It cannot skip a visible focus mark.

Do not use color alone as the instruction. Copy that says press the green button fails people who do not see that green. The label itself has to name the action.

This is not a conversion rate optimization (CRO) experiment on button copy. Changing Get a quote to Talk to sales while the fill still fails 4.5:1 leaves the same leak. Fix contrast first.

Unlike a full design and user experience engagement, this post covers only contrast on the primary action. For a look at whether Get a quote is actually readable on the live header, start with Get Free Assessment.

If this post is wrong, outdated, or you would take a different path

I write from work I have done on real sites. Search products change, and a step that was right when I published can go stale. I can also be wrong about the method.

If you disagree with the approach, the facts, or the outcome, I want the detail. Tell me what is off, what you would do instead, and where you saw it. I use that to correct the post so the next reader is not stuck.

This is not a comment thread. Use Contact me so the note is tied to this post and I can reply.

Share this post

Straight answers

Questions I hear a lot

How do you differ from a traditional agency?

You work with me, not a rotating cast. I audit, build, and train your team. Agencies often keep control and charge forever to run what you could own in-house.

What size of marketing budget makes sense for your services?

Honestly, you need enough marketing activity to make fixes worthwhile. Still very early stage? A course or specialist vendor may fit better. Already running a full in-house team? You probably want a full-time CMO, not me part-time.

Do you work with specific industries?

Yes: logistics, real estate, pro services, SaaS, local trades. Places where online leads hit the P&L fast. I skip healthcare and finance; compliance slows the work down.

What does a typical engagement look like?

Engagements start with a two-week audit of analytics, ads, SEO, and CRM. Then a 90-day plan focused on attribution, conversion, and what's leaking spend. Hands-on build and training along the way; at the end your team runs it.

How do I know if I need a digital marketing consultant versus hiring full-time?

If revenue is growing faster than you can hire marketing, fractional support fills the gap. Interim CMO work until you're ready for a full-time exec. Hiring help is available when you get there.

What happens after the engagement ends?

You keep logins, docs, and dashboards. Engagements are built so your team can maintain and troubleshoot. Some clients book a quarterly check-in; that's optional.

Drop Me A Message

Let’s start building the high-performance growth engine your brand deserves.

Ready to transform your digital presence into a high-performance engine? Whether you have a specific project in mind or need a comprehensive strategic consultation, I am here to bridge the gap between your current standing and your ultimate market goals. Reach out today to discuss how my specialized infrastructure and AI-driven strategies can scale your business. Fill out the form, and let’s start turning your vision into a measurable reality.

Get Free Assessment of Your Site

HAMMAD SHK

Copyright © 2026 HAMMAD SHK. All Rights Reserved