Colors in Design

Typography and Color: How to Pair Text Colors That Read Well

How to color headings, body text, muted text and links, why off-black often beats pure black, and how font size and weight change the contrast you need.

By ColorOverflow Editorial TeamUpdated November 13, 20268 min readIntermediate

Most of what people read on a screen is text, so text color does more work than any accent or illustration. The right text colors make a page easy to scan: the headline stands out, the body is comfortable to read for minutes at a time, the small print steps back, and links are obvious without shouting.

This guide is about choosing those colors together, as a system. It covers a simple set of text colors for hierarchy, why a softened near-black often reads better than pure black, how font size and weight change the contrast you need, and how to use colored headings and highlights without losing readability. Every ratio quoted here was calculated with the WCAG formula and cut to two decimals.

Text colors build hierarchy

Size and weight are the obvious tools for hierarchy, but color is just as strong. A design that uses one text color for everything feels flat, and the eye has no help deciding what to read first. A design with too many text colors feels noisy. Three or four roles cover almost every page:

  • Headings: the darkest, strongest color, so titles anchor the page.
  • Body text: slightly lighter than headings, still very high contrast, tuned for long reading.
  • Secondary text: captions, metadata, helper text and labels. Clearly lighter, but still comfortably readable.
  • Muted text: timestamps, placeholders and disabled labels. The lightest role, and the one most likely to fail contrast.

Here is one cool-gray set on a white background, with each ratio against white:

  • Headings #111827: 17.73:1.
  • Body #374151: 10.30:1.
  • Secondary #4B5563: 7.55:1.
  • Muted #6B7280: 4.83:1, just above the 4.5:1 that normal-size text needs.
  • A lighter gray, #9CA3AF: 2.53:1. Tempting for placeholders and fine print, but too faint for any text people need to read.
  • #111827
  • #374151
  • #4B5563
  • #6B7280
  • #FFFFFF

Heading, body, secondary and muted text on white. Every step passes for normal text.

Open in generatorPalette detailsVisualize

Shades & TintsTurn one color into a full scale of lighter and darker versions.

Why off-black often reads better than pure black

Pure black on pure white gives the highest possible contrast, 21:1. That sounds ideal, but on a bright screen the jump from glowing white to solid black can feel harsh, especially across long paragraphs. Many designers soften one side or both: a near-black for text, and sometimes a warm off-white for the page.

Softening costs very little contrast. Near-black #111827 on white is 17.73:1, and #1F2937 on white is 14.67:1. Both are still far above the 7:1 of WCAG's stricter AAA level. A near-black can also carry a hint of your palette's hue, a little blue or a little brown, so the text feels part of the design instead of sitting on top of it.

  • #1F2937 on a warm off-white #FAF7F2: 13.73:1. A calm pairing for articles and documentation.
  • #57534E, a warm gray, on the same off-white: 7.13:1. Good for secondary text in a warm palette.
  • #78716C on #FAF7F2: 4.48:1. It looks readable, but it falls just short of 4.5:1, so it fails for normal text.
  • #1F2937
  • #57534E
  • #FAF7F2
  • #C2410C

A softened near-black and a warm gray on off-white, with a burnt orange for headings or links.

Open in generatorPalette detailsVisualize

Don't soften too far. Mid-gray body text on a light gray background is one of the most common readability problems on the web. Keep body text dark enough that it would pass comfortably even on a cheap screen in daylight.

Size and weight change how much contrast you need

Large, heavy letters are easier to read than small, thin ones at the same contrast. WCAG reflects this with a lower minimum for large text, which it defines as at least 18 point, or 14 point bold. Our guide to color contrast and WCAG covers the exact thresholds and what counts as large.

In practice that gives you a little more freedom with headings. Orange #EA580C on white is 3.55:1. That fails for body text, but it meets the large-text minimum, so it can work for a big, bold heading. The brighter #F97316 is only 2.80:1 and fails even at large sizes.

WCAG only looks at size and bold. It doesn't account for the font itself, and fonts vary a lot. Some points the ratio alone won't tell you:

  • Thin and light weights have less ink, so they look paler than the ratio suggests. If you use a light weight for body text, give it more contrast than the minimum.
  • Fonts with small letter shapes, compared at the same point size, read smaller. Treat them as smaller text.
  • Small text in a secondary gray is a double risk: low contrast and small size together. Captions and footnotes deserve a darker gray than you might first pick.
  • Bold doesn't rescue very low contrast. It helps at the margin, not for a pale gray that is far below the line.
Read the full guideColor Contrast and WCAG: A Practical Guide

Colored headings

Colored headings are a simple way to bring a brand color into a text-heavy page. The rule is to choose the shade for the job: a deep or mid-dark version of the brand hue, not the bright version used for buttons or illustrations.

  • Violet #7C3AED on white: 5.69:1. Passes at any size.
  • Teal #0F766E on white: 5.47:1. Passes at any size.
  • Burnt orange #C2410C on white: 5.17:1. A readable stand-in for a bright orange brand color.
  • Deep navy #1E3A8A on white: 10.35:1. Strong enough to use for long subheadings.

Keep body text neutral when headings are colored. Two strong text colors compete, and colored body text is tiring to read across a whole page. Limit colored text to one hue, and use it consistently, so readers learn what it means.

  • #0F766E
  • #111827
  • #4B5563
  • #F0FDFA
  • #FFFFFF

Teal headings, near-black body, gray captions, with a very light teal for callout boxes.

Open in generatorPalette detailsVisualize

A link has two jobs: it must be readable against the background, and it must be recognizable as a link within the surrounding text. Color alone often fails the second job. WCAG asks that color is not the only way information is shown, and a link that differs from body text only by hue can disappear for people with color vision deficiency.

Take blue #2563EB. On white it is 5.16:1, so it's readable. Against body text #374151, though, the two colors differ by only 1.99:1 in lightness. Without an underline, a reader who can't see the hue difference may not spot the link at all. Against darker body text #111827 the same blue differs by 3.43:1, which stands out more, but an underline is still the most reliable cue.

  • Underline links in body text. Removing the underline is reasonable in navigation, where the layout already says these are links.
  • Pick a link color that passes 4.5:1 against the background, such as #1D4ED8 at 6.70:1 on white.
  • Give hover and keyboard focus a visible change, such as a thicker underline or a background tint, not only a slight color shift.
  • Keep visited links distinct if your readers move through many pages, but make sure the visited color passes contrast too.

Highlighted and emphasized text

Highlights, badges and marked text put text on a colored background, so the check is between the text and that background, not white. Light highlight colors are the easy case: near-black #111827 on a pale yellow #FEF08A is 15.24:1, and body gray #374151 on it is 8.85:1.

  • Keep highlight backgrounds light and the text dark. A saturated highlight with white text needs a much darker color than you'd expect.
  • Use highlights sparingly. If half a paragraph is highlighted, nothing is.
  • Don't rely on the highlight color alone to carry meaning, such as green for correct and red for wrong. Add a word or an icon.
  • For text over photos, add a solid or semi-transparent panel behind it. A photo's lightness changes from pixel to pixel, so no single text color passes everywhere.

Text colors in dark mode

On dark backgrounds the same roles apply in reverse. Avoid pure white body text on a near-black page for the same reason you'd avoid pure black on white: it's more contrast than long reading needs. Light gray #E5E7EB on #111827 is 14.32:1, plenty for body text. For secondary text, #9CA3AF on #111827 is 6.98:1, while #6B7280 drops to 3.66:1, too low for normal text.

Link and accent colors usually need a lighter shade in dark mode. Blue #2563EB, fine on white, is only 3.43:1 on #111827. A lighter blue, #60A5FA, reaches 6.97:1.

  • #111827
  • #E5E7EB
  • #9CA3AF
  • #60A5FA

A dark page with light gray body, mid-gray secondary text and a lighter blue for links.

Open in generatorPalette detailsVisualize

A quick checklist for text colors

  1. Choose three or four text roles from a single gray scale, and stick to them.
  2. Use a near-black for headings and a slightly lighter dark gray for body text.
  3. Check every role against every background it appears on, including cards, highlights and dark mode.
  4. Keep muted text at or above 4.5:1 unless it really is decorative or disabled.
  5. Use colored text for headings and links only, in a shade that passes for its size.
  6. Underline links in running text so they don't depend on color alone.
  7. Preview the colors on a real layout at real sizes before you commit.
Contrast CheckerTest a text and background pair against WCAG AA and AAA.

To see a palette's text colors in context, the Palette Visualizer's typography preview sets real headings and paragraphs in your colors, and the website mockups show how they hold up next to buttons and cards.

Palette VisualizerSee your palette on real designs, outfits and rooms.

Put it into practice

Unsaved changes

“” has changes that aren't saved to your wishlist. Save them before continuing?