Why it happens so reliably
Relative luminance weights green at 0.7152, red at 0.2126 and blue at 0.0722. A saturated orange or lime is far brighter to that formula than it looks to a designer choosing it, so white sitting on it has much less room than expected.
Brand colors are also chosen at large sizes, on a logo or a hero, where the 3:1 large text bar applies. The button label is 15px, where the bar is 4.5:1, and nobody re-checks.
What it looks like
Substack's Subscribe button is a real example, and it is a well-designed product. White on their orange:
Now the same button with near-black text instead. The brand color is untouched:
A filled button is two checks, not one
People conflate these constantly. They are separate, and both are required:
| What | Against what | Needs |
|---|---|---|
| The label | The button fill | 4.5:1 (3:1 if large) |
| The fill's own edge | The page behind it | 3:1 |
The second one catches dark-mode buttons in particular. A violet that is fine on a light page can sit at 2.6:1 against a dark card, which is a button with no visible boundary. Our own palette test caught exactly that on this site.
Fixing it without losing the brand
- 1.Try near-black on the fill first. It costs nothing and it usually wins.
- 2.If the brand color is dark, try white. One of the two almost always clears 4.5:1.
- 3.If neither does, the color is too mid-toned for a filled button. Darken it for that use only, holding hue in OKLCh so it stays recognisably the brand.
- 4.Never solve it by making the label bigger unless the button was genuinely meant to be large. 24px button text to dodge a contrast check is a worse design than a darker fill.
Do it on your own brand color
Two ways round this, and they answer different questions. If you want to keep the button and know what white needs, check the pair. If the real problem is that you only have one brand color and need a usable range of it, build the scale instead: the step that works as a button surface is almost never the step that works as a link on white.
Contrast checkerPut white on your brand color and get the nearest passing shade, hue held exactly.Accessible rampTurns the one color into a full scale, with each step already measured against white and black.Common questions
- Does white text on a brand color need to pass contrast?
- Yes. A button label is text and needs 4.5:1 against the fill it sits on, or 3:1 if it is 24px or larger, or 18.66px at weight 700 or more.
- Should I change my brand color if white fails on it?
- Usually not. Try near-black text on the same fill first; on most mid-tone and light brand colors it passes comfortably. Only if neither white nor near-black clears the threshold does the fill itself need a darkened variant.
- Does the button itself need contrast against the page?
- Yes, 3:1, as a user interface component. That is a separate check from the label, and it is the one that catches buttons on dark backgrounds.