Most small business brand colours were chosen for a logo, a sign or a van, not for paragraphs of text on a screen. That’s fine until the website goes up and the links, buttons and headings are all in that one bright colour, and some of the people visiting can’t comfortably read them.
Clients often arrive with one hex code from a logo file and a hope that it will do everything. It never quite does. You rarely need to change the brand, though. You need a few more shades of it, and a clear idea of which shade goes where.
Why contrast matters
Low contrast doesn’t only affect people with a diagnosed visual impairment. It affects anyone reading on a phone in sunlight, anyone with tired eyes at the end of the day, and many older readers, because sensitivity to contrast tends to fall with age. If a call to action is hard to read, fewer people act on it.
There’s also a standard to meet. The Web Content Accessibility Guidelines, WCAG 2.2, set minimum contrast ratios, and level AA is the level most accessibility laws, public sector rules and client contracts point to. Meeting it is a reasonable baseline for any business site.
The numbers you need
Contrast is measured as a ratio between the relative luminance (perceived brightness) of two colours. It runs from 1:1, the same colour on itself, to 21:1, black on white.
| What you’re checking | AA | AAA | WCAG criterion |
|---|---|---|---|
| Normal text | 4.5:1 | 7:1 | 1.4.3 and 1.4.6 |
| Large text: at least 24px regular, or about 18.7px bold | 3:1 | 4.5:1 | 1.4.3 and 1.4.6 |
| UI components and meaningful graphics: input borders, icons, focus indicators, chart segments | 3:1 | none | 1.4.11 |
A few details trip people up:
- Large text is defined in points: 18pt regular or 14pt bold. In CSS pixels that’s 24px, or about 18.7px if bold. Your 16px body text is never large text, however important it is.
- There’s no rounding up. A ratio of 4.49:1 fails AA for normal text. Some tools round to one decimal place and show it as 4.5. The Colour Converter rounds down, so a pass really is a pass.
- Non-text contrast (criterion 1.4.11) covers the parts of a component you need to see to use it. W3C’s guidance on non-text contrast explains that a button with a clear text label doesn’t need its background to stand out from the page at 3:1, because the text identifies it. A text field whose only visible edge is its border does need that border at 3:1.
Why bright brand colours fail as text
Bright oranges, yellows, teals and light greens are bright precisely because they have high luminance. White also has high luminance, so the two sit close together on the scale and the ratio comes out low.
Here’s a worked example. Say the logo colour is a cheerful orange, #ff6b1a. I put it into the Colour Palette Generator, which builds an 11-step scale from 50 (lightest) to 950 (darkest) and places the base colour on the step that matches its lightness. This one lands on 400. I then checked every shade against white and black with the WCAG formula.
| Step | HEX | Contrast with white | Contrast with black | Good for |
|---|---|---|---|---|
| 50 | #fff3ed |
1.08:1 | 19.29:1 | Page and section backgrounds |
| 100 | #ffe3d5 |
1.22:1 | 17.20:1 | Highlight panels, hover backgrounds |
| 200 | #ffc8af |
1.48:1 | 14.13:1 | Decorative borders, tags with dark text |
| 300 | #ffa177 |
1.97:1 | 10.61:1 | Links and accents in dark mode |
| 400 (base) | #ff6b1a |
2.84:1 | 7.36:1 | Buttons and large areas with dark text |
| 500 | #e64900 |
3.94:1 | 5.31:1 | Large or bold text on white only |
| 600 | #bd3800 |
5.63:1 | 3.72:1 | Body text, links and buttons with white text |
| 700 | #9c2a00 |
7.65:1 | 2.74:1 | Text that meets AAA on white |
| 800 | #7e1e00 |
10.13:1 | 2.07:1 | Headings, dark panels |
| 900 | #641300 |
12.84:1 | 1.63:1 | Dark backgrounds with light text |
| 950 | #470600 |
16.22:1 | 1.29:1 | Dark mode surfaces |
Contrast works the same in both directions, so the “with white” column tells you both how a shade reads as text on a white page and how white text reads on that shade.
The brand orange itself manages 2.84:1 against white. That fails for normal text, fails for large text, and even fails the 3:1 needed for an icon. Yet black text on it scores 7.36:1, comfortably past AAA. The colour isn’t the problem. Using it for the wrong job is.
Practical fixes that keep the brand
Use a darker shade for text and links
Pick a step that passes 4.5:1 on your background and use it for links, small headings and anything else people need to read. In the example, 600 is the first step that does. It reads as a deeper version of the same orange, so the brand still comes through.
If normal text fails, the Colour Converter suggests the closest shade of your colour that passes AA. For this orange it suggests #d04a00, which reaches exactly 4.5:1. I’d still choose something with a bit of headroom, like the 600 step, so a small tweak later doesn’t push it under.
Keep the bright colour for big areas, with dark text
The bright base colour is perfect for button backgrounds, banners and section blocks, as long as the text on top is dark. White text on bright orange is a common habit, and in this example that pairing fails at 2.84:1. Dark text on it passes easily.
Watch near-black greys, though. A dark slate such as #111827 on the 500 step comes out at 4.49:1, a hair under the line. Check the actual pair you plan to use.
Check dark mode separately
A shade that works on white often fails on a dark background, and the other way round. Against a typical dark surface of #121212, the 600 step drops to 3.32:1 and fails for body text, while the original 400 orange reaches 6.57:1 and the 300 step 9.47:1. So the bright colour you couldn’t use for links in light mode may be exactly the right one in dark mode.
In practice that means two link colours, one per theme, set as CSS custom properties. The Colour Palette Generator exports the whole scale as CSS variables, Tailwind or SCSS.
Make focus states visible
Keyboard users need to see which link or button is focused. WCAG requires a visible focus indicator, and the 3:1 rule for non-text contrast is the sensible benchmark for it: the ring should stand out against whatever surrounds it. A pale brand-coloured ring on a white page usually doesn’t.
I tend to use a solid outline in a dark shade, offset by a couple of pixels. If you prefer a softer ring made from a box shadow (the Box Shadow Generator can make one with zero offset, zero blur and a few pixels of spread), add outline: 2px solid transparent as well. Windows forced colours mode removes box shadows, and the transparent outline then becomes visible instead.
Don’t rely on colour alone
WCAG criterion 1.4.1 says colour shouldn’t be the only way information is shown. Links inside paragraphs are the usual offender: a brand-coloured link with no underline can be invisible to someone who can’t tell your orange from your body text. Keep the underline in running text. The same applies to form errors (add an icon or message, not just a red border) and to charts (add labels or patterns).
Be careful with text over images and gradients
Text over a photo or a gradient has to meet the same ratios, measured against the lightest part of the background behind the letters, not the average. A hero image that looks dark overall often has a bright patch exactly where the heading sits.
The usual fix is a scrim: a semi-transparent dark gradient between the image and the text. You can build one in the CSS Gradient Generator, which supports transparency in colour stops. For a plain gradient background, check your text colour in the Colour Converter against both ends and the middle. The middle matters: a gradient between two very different hues can pass through a duller, darker colour than either end, which is bad news for dark text.
A note on APCA and WCAG 3
You may come across APCA, a newer way of measuring contrast that takes font size and weight into account and treats dark mode differently. It has been explored as part of the work on WCAG 3, which is still a draft. For now, WCAG 2.2 is the standard that laws and contracts refer to, so meet that first and treat APCA as a second opinion.
Turning your logo colour into a palette
This is the routine I follow when a client hands over a logo:
- If you don’t have the exact colour, drop the logo into the Colour Palette Generator’s image extractor to find it. Large flat areas give the most reliable result.
- Generate the 50 to 950 scale and leave the base on Nearest unless your design system says otherwise.
- Read the contrast ratings on each swatch and decide on your text and link shade for light mode, and another for dark mode.
- Check the exact pairs you’ll ship in the Colour Converter: button text on button background, link on page background, focus ring on page background, and any text over images.
- Add the neutral scale if you need greys that sit well with the brand, export everything, and write down which step is for what so the next person doesn’t use the 400 for body text.
If you’re about to launch, contrast is one item on a longer list. The website launch checklist covers the rest.
