High Contrast Color Palettes, With Ratios Checked

A high contrast palette is a set of brand colours where text stays easy to read on its background. WCAG 2.2 measures this as a ratio from 1:1 to 21:1. Body text needs at least 4.5:1 for level AA and 7:1 for AAA; large text needs 3:1 and 4.5:1. The palettes here list every pair.

WCAG 2.2 contrast minimums
ContentLevel AALevel AAA
Body text4.5:17:1
Large text (18pt, or 14pt bold)3:14.5:1
Icons, input borders, focus rings3:1No extra level
Logos and pure decorationNo requirementNo requirement

Updated

Most palette sites show pretty swatches side by side, which says nothing about whether text placed on them can be read. Each palette below gives a colour a job (background, text, secondary text, accent, text on the accent) and checks the pairs you would really put together on a page.

Palette tester

Pick a palette, then change any colour. Every pair is rechecked as you type.

Starting palette: Ink on paper, Night shift, Forest ledger, Harbor blue, Warm clay

Opening hours

Open Tuesday to Saturday, 9 to 5. Walk-ins welcome before noon.

Closed on public holidays.

Book a visit

Everything is calculated in your browser.

The five palettes and their ratios

Ratios are calculated with the WCAG 2.2 formula and shown cut down to two decimals.

Every checked pair in the five palettes
PalettePairRatioBody textAAA body text
Ink on paperBody text #111827 on Background #FFFFFF17.73:1AAAAA
Ink on paperSecondary text #4B5563 on Background #FFFFFF7.55:1AAAAA
Ink on paperAccent and buttons #1D4ED8 on Background #FFFFFF6.70:1AANo
Ink on paperText on the accent #FFFFFF on Accent and buttons #1D4ED86.70:1AANo
Night shiftBody text #F8FAFC on Background #0B122017.89:1AAAAA
Night shiftSecondary text #CBD5E1 on Background #0B122012.61:1AAAAA
Night shiftAccent and buttons #FBBF24 on Background #0B122011.21:1AAAAA
Night shiftText on the accent #0B1220 on Accent and buttons #FBBF2411.21:1AAAAA
Forest ledgerBody text #1B3A2A on Background #F7F5EF11.42:1AAAAA
Forest ledgerSecondary text #44403C on Background #F7F5EF9.42:1AAAAA
Forest ledgerAccent and buttons #9A3412 on Background #F7F5EF6.70:1AANo
Forest ledgerText on the accent #FFFFFF on Accent and buttons #9A34127.30:1AAAAA
Harbor blueBody text #FFFFFF on Background #0F2E4C13.85:1AAAAA
Harbor blueSecondary text #D6E4F0 on Background #0F2E4C10.69:1AAAAA
Harbor blueAccent and buttons #7DD3FC on Background #0F2E4C8.31:1AAAAA
Harbor blueText on the accent #0F2E4C on Accent and buttons #7DD3FC8.31:1AAAAA
Warm clayBody text #431407 on Background #FFF7ED14.74:1AAAAA
Warm claySecondary text #57534E on Background #FFF7ED7.18:1AAAAA
Warm clayAccent and buttons #B91C1C on Background #FFF7ED6.09:1AANo
Warm clayText on the accent #FFFFFF on Accent and buttons #B91C1C6.47:1AANo

Use a palette in your CSS

Ink on paper as CSS custom properties

Name variables by role, not by colour, so swapping a palette later is one edit per line.

<style>
:root {
  --bg: #FFFFFF;
  --text: #111827;
  --muted: #4B5563;
  --accent: #1D4ED8;
  --on-accent: #FFFFFF;
}
body { background: var(--bg); color: var(--text); font: 16px/1.5 system-ui, sans-serif; padding: 16px; }
small { color: var(--muted); }
button { background: var(--accent); color: var(--on-accent); border: 0; border-radius: 999px; padding: 8px 16px; font: inherit; }
</style>
<p>Fresh bread from 7am, every day but Monday.</p>
<small>Prices include tax.</small>
<p><button>Order ahead</button></p>

The contrast formula in JavaScript

The same calculation the tester runs, written from the W3C definition of relative luminance.

function luminance(hex) {
  const n = parseInt(hex.replace("#", ""), 16);
  const lin = (c) => {
    const s = c / 255;
    return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
  };
  return 0.2126 * lin(n >> 16) + 0.7152 * lin((n >> 8) & 255) + 0.0722 * lin(n & 255);
}

function contrast(a, b) {
  const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
  return (hi + 0.05) / (lo + 0.05);
}

contrast("#111827", "#FFFFFF"); // about 17.7

Why five roles and not five swatches

A palette of five colours has ten possible pairs, and most of them never meet on a real page. Naming a role for each colour tells you which pairs matter, so you test four combinations instead of guessing.

The role that most often fails is secondary text: the pale grey used for dates, captions and footnotes. It is also the text people squint at most.

Adapting a palette to your brand

Keep your brand colour as the accent and adjust its lightness until the button text passes. A shade darker or lighter usually keeps the brand feel while fixing the ratio.

If your brand colour is a light yellow or a pale blue, use it for backgrounds and large shapes, and pick a dark partner for anything people need to read.

How it works

  1. Each colour is turned into relative luminance: how bright it looks, from 0 for black to 1 for white.
  2. The lighter value plus 0.05 is divided by the darker value plus 0.05. That number is the contrast ratio.
  3. The ratio is compared with the WCAG minimum for the kind of content, without rounding.
  4. A pair only counts if you use it that way: secondary text is checked on the background, button text on the accent.

Tips

Frequently asked questions

What contrast ratio counts as high contrast?

There is no single official line called high contrast. WCAG level AA asks for 4.5:1 for normal text and level AAA asks for 7:1, so many designers treat 7:1 for body text as the high contrast target.

What size counts as large text?

WCAG treats text of at least 18 point, or 14 point bold, as large. The W3C explainer puts those at roughly 24px and 18.5px in CSS pixels.

Can I round 4.47 up to 4.5?

No. The W3C says the ratio is not rounded, so a pair at 4.499:1 does not meet 4.5:1. The tester cuts values down for this reason.

Do buttons and icons need contrast too?

Yes. WCAG 2.2 success criterion 1.4.11 asks for at least 3:1 between parts of controls and meaningful graphics and the colours next to them.

Does my logo have to pass?

No. Text that is part of a logo or brand name has no contrast requirement under 1.4.3. Everything else on the page around it still does.

Related: Color contrast checker, Accessible color palette generator, Bad color contrast examples and fixes, Best fonts for websites.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap