Software & Apps

How to Choose Readable Text and Background Colors

Learn how to pick text and background colors that stay readable and pass WCAG contrast checks — with a free checker and worked examples.

Picking colors for a website usually starts with taste: a brand blue here, a soft gray there, a warm accent for buttons. Readability, though, is not decided by taste. It is decided by the distance between two colors — how much lighter one is than the other when both are reduced to brightness. Get that distance wrong and your text quietly becomes hard to read, even for people with perfect eyesight, and nearly unreadable for people with low vision or color blindness.

This guide shows you how to choose text and background colors that stay readable: what the contrast ratio measures, the exact WCAG thresholds, and how to test any pair in seconds with a free browser tool — plus three real tested pairs and the mistakes that trip up even experienced designers.

Why contrast matters

Contrast is the difference in relative luminance between a foreground color (usually text) and the color behind it. Luminance is a measure of how much light a color reflects, weighted toward the colors human eyes are most sensitive to — green counts most, then red, then blue. The contrast ratio is expressed as a number like 4.5:1, meaning the lighter color is 4.5 times as luminant as the darker one. The scale runs from 1:1 (two identical colors, completely unreadable) to 21:1 (black on white, the maximum possible).

That number matters because reading is not just about sharp eyesight. Roughly one in twelve men and one in two hundred women worldwide has some form of color vision deficiency, and many more people deal with low vision, aging eyes, glare on a phone screen, or a monitor that washes colors out. A pair that looks fine on your calibrated display can fall apart on a phone in sunlight. A strong contrast ratio is the safety margin that keeps text legible across all of those conditions.

It also matters because hue difference is not the same as contrast. Red text on green text looks dramatically different to someone with full color vision, yet the two colors can have almost identical luminance, giving a contrast ratio near 1:1. That is why "these colors look different enough" is a trap, and why you should always measure the pair rather than eyeballing it. Two colors that sit opposite each other on the color wheel can still fail, while two close neighbors in hue — a very dark navy and white, for example — can pass easily.

The WCAG thresholds give you concrete targets. For normal body text, WCAG level AA requires a contrast ratio of at least 4.5:1. Large text — defined as at least 18 points in regular weight, or 14 points in bold — needs at least 3:1 at level AA. The stricter AAA level raises the bar to 7:1 for normal text and 4.5:1 for large text. In practice, aiming for AA on all body text and AAA where you can manage it is a sensible, widely used standard, and it is the standard many accessibility laws and procurement policies point to.

One more principle before we measure anything: never rely on color alone to carry meaning. If an error message is red text on white, a reader who cannot distinguish red still needs a word like "Error" or an icon to tell them something went wrong. Contrast makes text readable; labels, icons, and underlines make meaning available to everyone.

Check a pair with the contrast checker

The fastest way to test a pair is FBSubNet's Two-Color Contrast Checker, a free tool that runs entirely in your browser. Enter the foreground (text) and background HEX values, run the tool, and it reports the WCAG contrast ratio plus pass or fail results for AA normal text, AA large text, and AAA normal text. Nothing you type is uploaded anywhere.

Here is the workflow. First, copy the HEX codes for the pair you want to test from your design file or stylesheet. Second, paste them into the tool's foreground and background fields. Third, run the tool and read the ratio and the three pass/fail verdicts. Fourth, decide based on text size: body copy needs the AA normal-text pass, while a big headline can get away with the large-text pass. If a verdict you need shows a fail, adjust one color and test again. The loop takes under a minute, so there is no reason to guess.

To show what this looks like in practice, we tested three sample pairs through the checker. The results below are the actual ratios the tool reports for these HEX values.

Three pairs, three verdicts

Pair 1 — Dark slate text on white: #1F2937 on #FFFFFF, ratio 14.68:1. This passes everything: AA normal text, AA large text, and AAA normal text. Dark gray instead of pure black is a common choice for body copy because it softens the harshness of black on white while keeping a huge safety margin. If your design uses a near-black gray for text, you are almost certainly in good shape on a white background.

Pair 2 — Medium gray text on white: #767676 on #FFFFFF, ratio 4.54:1. This passes AA normal text, but only just — 4.54:1 clears the 4.5:1 bar by a whisker — and it fails AAA normal text. This is the classic borderline case. Medium grays are popular for secondary text, captions, and muted labels, and #767676 is about as light as a gray can be on white while still passing AA. Anything lighter, like #AAAAAA, drops to 2.32:1 and fails AA outright. Treat 4.54:1 as a floor, not a target: a tiny change in the background, such as placing the text on a light gray card instead of pure white, can push a borderline pair below the line.

Pair 3 — Burnt orange text on white: #E76F51 on #FFFFFF, ratio 3.09:1. This fails AA normal text but passes AA large text, since it clears the 3:1 bar. It is a perfect illustration of why the size distinction exists. That warm orange is a lovely brand accent, and it works fine for a large headline or a big call-to-action label — but set a paragraph of body copy in it on white and a significant share of readers will struggle. The fix is not to abandon the color; it is to reserve it for large text and find a darker shade of the same hue for body copy, as the next section shows.

The pattern across all three pairs is worth memorizing. Dark text on a light background almost always passes, light text on a dark background passes when the background is dark enough, and mid-tone colors — medium grays, light oranges, soft yellows, pastel blues — are where failures hide. Yellow is a notorious case: even a vivid yellow on white scores barely above 1:1, because yellow is one of the brightest colors in luminance terms. If your brand palette leans pastel or bright, test every text pair before you ship it.

Adjust colors deliberately

When a pair fails, you have three levers: darken the text, lighten the background, or both. The trick is to move along the lightness axis while keeping the hue recognizable, so the result still looks like your brand. Most color pickers let you do this by lowering the lightness (or raising the darkness) of one color in small steps and re-testing after each step.

Take the failing orange pair above. #E76F51 on white scores 3.09:1, short of the 4.5:1 needed for body text. Darkening the orange toward a burnt sienna, while keeping the same warm hue, climbs steadily: each step down in lightness buys ratio. Once the darker shade crosses 4.5:1, you have a body-text version of your brand color that still reads as the same family. Keep the brighter original for large headings, buttons with large labels, and decorative accents, and use the darker shade wherever paragraphs, captions, or small labels appear. Two shades of one hue, each used where it passes, is a cleaner solution than swapping in an unrelated color.

The same logic works in reverse for dark themes. White text on a deep navy background such as #1E3A8A scores 10.36:1, an easy AAA pass. But medium gray text on that same navy — a combination dark-mode designs love for secondary text — can fall below 4.5:1 quickly. Dark mode is not automatically accessible: every pair must be re-tested against its dark background. Check both themes separately, pair by pair.

Also test text where it actually appears, not just on a plain swatch. Text over a photo, gradient, or patterned card has no single background color, so the flat-swatch ratio does not apply. In those cases, sample the lightest and darkest parts of the image behind the text and test both, or add a solid overlay behind the text to pin the background to a known color. Buttons deserve the same treatment: the label must contrast with the button's fill, and the button should contrast with the page behind it at 3:1.

Finally, build the checks into your workflow rather than doing them once at launch. Brand palettes drift — a new tint, a lightened background, an accent reused as body text — and each change can quietly break a pair that used to pass. Re-running the checker on your core pairs whenever the palette changes takes minutes. If you use a related resource like the HEX color guide to manage palette values, keep the tested pairs documented alongside the HEX codes so the next person to touch the design knows which combinations are approved.

Common mistakes to avoid

Light gray body text on white. Placeholder-style grays like #AAAAAA or #CCCCCC look elegant in a mockup and fail in the real world, scoring around 2:1. Reserve light grays for borders, dividers, and large decorative elements — never for text people must read.

Using a brand accent as body text. Accents are chosen to stand out, not to be read at length. A bright blue, coral, or yellow that pops as a button or underline usually fails as paragraph text. Use the accent at large sizes and a darker shade for body copy.

Judging contrast by eye alone. Screens differ, eyes differ, and hue tricks the eye. A pair that looks fine to you can measure 2.5:1. Measure every pair with the checker before you commit to it.

Forgetting links and form text. Links must be distinguishable from surrounding body text — an underline or bold weight plus a color that itself contrasts with the background. Placeholder text inside form fields is often rendered in a light gray that fails; test it as real text, not decoration.

Testing only one theme. Light and dark modes are two different contrast problems. A pair that passes in one can fail in the other, so verify both.

Frequently asked questions

What is a good contrast ratio for website text?

Aim for at least 4.5:1 for normal body text (WCAG AA) and 7:1 for AAA. Large text — 18 points or larger, or 14 points bold — needs at least 3:1 at AA. Higher is always better.

Does passing a contrast checker make my site accessible?

No. Contrast is one requirement among many. Keyboard navigation, alt text for images, form labels, heading structure, and not relying on color alone all matter too. A passing ratio means your text is readable; it does not certify the whole page.

Can I use my brand colors and still pass?

Almost always, yes. The fix is usually a darker or lighter shade of the same hue, not a different color. Keep the vivid shade for large text and accents, and derive a darker variant for body copy, testing both with the checker.

Readable color choices decide whether a large share of your audience can actually use what you built. Measure each pair, document your passing combinations, and re-test whenever the palette changes. Start with the pair you are least sure about — paste it into the Two-Color Contrast Checker and see where it lands.