OKLCH Studio · Accessible palettes · Data visualisation

Colorblind-friendly chart palette: six colours with a strict ΔE check

Updated 2026-10-19

If your audience may include people with colour-vision deficiency, which at roughly one in twelve men is not a niche, the safest chart is one that uses few colours and keeps them far apart. This palette trades quantity for separation: six colours, with a minimum pairwise difference well above the one used for the eight-colour set.

Every series colour is at least 3:1 against the chart background, and every pair is tested under normal vision and simulated protanopia, deuteranopia and tritanopia. The check is strict enough that the palette also tolerates blur, small markers and print on a mid-quality printer, all of which shrink differences further.

This page is the cautious option. Use it when charts are the product, as in analytics or public reporting, or when the people reading them cannot ask you what a colour means. Chart text is held at AAA here, as small axis labels are often the first thing to fail.

How to build a palette like this by hand is explained in the accessible colour palette guide; this page is the finished, verified result.

The palette: light and dark

Hex values are the sRGB result after gamut mapping. The oklch() values are those of the final hex, so converting either gives the same colour.

Light chart: series, with contrast on the chart background

  • 1. #004B988.29:1
  • 2. #B484003.26:1
  • 3. #7730009.24:1
  • 4. #9D6FE33.50:1
  • 5. #4C9E843.12:1
  • 6. #7D66225.37:1

Light theme

  • Chart background

    #F9FCFF

    oklch(0.990 0.005 247.9)

    Sample text

  • Chart text

    #1D2022

    oklch(0.241 0.006 236.8)

    Sample text

  • Axis labels

    #55585C

    oklch(0.459 0.008 255.5)

    Sample text

  • Axis line

    #83878B

    oklch(0.621 0.008 247.9)

    Sample text

  • Gridline

    #CCD0D5

    oklch(0.856 0.008 253.9)

    Sample text

  • Series 1

    #004B98

    oklch(0.421 0.142 255.6)

    Sample text

  • Series 2

    #B48400

    oklch(0.6433 0.1323 82.79)

    Sample text

  • Series 3

    #773000

    oklch(0.403 0.112 46.6)

    Sample text

  • Series 4

    #9D6FE3

    oklch(0.640 0.171 299.9)

    Sample text

  • Series 5

    #4C9E84

    oklch(0.640 0.090 170.2)

    Sample text

  • Series 6

    #7D6622

    oklch(0.520 0.090 89.9)

    Sample text

Dark chart: series, with contrast on the chart background

  • 1. #86B8FF8.90:1
  • 2. #CC59004.31:1
  • 3. #5A76E44.44:1
  • 4. #98B3057.58:1
  • 5. #FFB5A810.73:1
  • 6. #A969884.37:1

Dark theme

  • Chart background

    #141618

    oklch(0.199 0.005 248.1)

    Sample text

  • Chart text

    #E8EBEF

    oklch(0.939 0.006 255.5)

    Sample text

  • Axis labels

    #AEB1B6

    oklch(0.760 0.008 260.7)

    Sample text

  • Axis line

    #717579

    oklch(0.560 0.008 248.0)

    Sample text

  • Gridline

    #33373A

    oklch(0.334 0.008 240.1)

    Sample text

  • Series 1

    #86B8FF

    oklch(0.775 0.115 257.2)

    Sample text

  • Series 2

    #CC5900

    oklch(0.600 0.166 47.2)

    Sample text

  • Series 3

    #5A76E4

    oklch(0.600 0.169 269.9)

    Sample text

  • Series 4

    #98B305

    oklch(0.7206 0.1701 119.98)

    Sample text

  • Series 5

    #FFB5A8

    oklch(0.839 0.089 30.2)

    Sample text

  • Series 6

    #A96988

    oklch(0.600 0.091 349.7)

    Sample text

Contrast table: every verified pair

Pass or fail uses the raw WCAG 2.x ratio; the ratio shown is floored to two decimals so a near miss is never rounded up. APCA Lc is signed: positive is dark on light, negative is light on dark. Each row opens the pair in the checker.

Light theme: 9 pairs
PairWCAG ratioTargetNormal AA / AAALarge AA / AAAAPCA LcAPCA tierCheck
Chart text on background#1d2022 on #f9fcff15.91:1AAA 7:1Pass / PassPass / Pass+101.3Lc 75: body textOpen in checker
Axis labels on background#55585c on #f9fcff6.94:1AA 4.5:1Pass / FailPass / Pass+82.8Lc 75: body textOpen in checker
Axis line on background#83878b on #f9fcff3.51:13:1 (WCAG 1.4.11)Fail / FailPass / Fail+61.8Lc 60: larger content textOpen in checker
Series 1 on background#004b98 on #f9fcff8.29:13:1 (WCAG 1.4.11)Pass / PassPass / Pass+86.6Lc 75: body textOpen in checker
Series 2 on background#b48400 on #f9fcff3.26:13:1 (WCAG 1.4.11)Fail / FailPass / Fail+58.8Lc 45: headlines and large textOpen in checker
Series 3 on background#773000 on #f9fcff9.24:13:1 (WCAG 1.4.11)Pass / PassPass / Pass+89.3Lc 75: body textOpen in checker
Series 4 on background#9d6fe3 on #f9fcff3.50:13:1 (WCAG 1.4.11)Fail / FailPass / Fail+61.4Lc 60: larger content textOpen in checker
Series 5 on background#4c9e84 on #f9fcff3.12:13:1 (WCAG 1.4.11)Fail / FailPass / Fail+57.1Lc 45: headlines and large textOpen in checker
Series 6 on background#7d6622 on #f9fcff5.37:13:1 (WCAG 1.4.11)Pass / FailPass / Pass+75.5Lc 75: body textOpen in checker
Dark theme: 9 pairs
PairWCAG ratioTargetNormal AA / AAALarge AA / AAAAPCA LcAPCA tierCheck
Chart text on background#e8ebef on #14161815.16:1AAA 7:1Pass / PassPass / Pass−93.7Lc 75: body textOpen in checker
Axis labels on background#aeb1b6 on #1416188.43:1AA 4.5:1Pass / PassPass / Pass−59.1Lc 45: headlines and large textOpen in checker
Axis line on background#717579 on #1416183.90:13:1 (WCAG 1.4.11)Fail / FailPass / Fail−28.5Below Lc 30Open in checker
Series 1 on background#86b8ff on #1416188.90:13:1 (WCAG 1.4.11)Pass / PassPass / Pass−61.9Lc 60: larger content textOpen in checker
Series 2 on background#cc5900 on #1416184.31:13:1 (WCAG 1.4.11)Fail / FailPass / Fail−32.6Lc 30: non-text and incidentalOpen in checker
Series 3 on background#5a76e4 on #1416184.44:13:1 (WCAG 1.4.11)Fail / FailPass / Fail−33.1Lc 30: non-text and incidentalOpen in checker
Series 4 on background#98b305 on #1416187.58:13:1 (WCAG 1.4.11)Pass / PassPass / Pass−54.3Lc 45: headlines and large textOpen in checker
Series 5 on background#ffb5a8 on #14161810.73:13:1 (WCAG 1.4.11)Pass / PassPass / Pass−72.0Lc 60: larger content textOpen in checker
Series 6 on background#a96988 on #1416184.37:13:1 (WCAG 1.4.11)Fail / FailPass / Fail−32.4Lc 30: non-text and incidentalOpen in checker

Colour-blind check

Colours are simulated with the Machado et al. (2009) model at full severity (culori). The figure is the smallest ΔE-OK ×100, the Euclidean distance in OKLab, between any two colours. The build fails if it drops below 11. Still pair colour with labels or patterns (WCAG 1.4.1).

Light chart theme
VisionSimulated coloursMin ΔE-OK ×100Closest pair
Normal vision13.1 (≥ 11)2 and 6
Protanopia11.4 (≥ 11)2 and 5
Deuteranopia13.0 (≥ 11)5 and 6
Tritanopia11.3 (≥ 11)4 and 6
Dark chart theme
VisionSimulated coloursMin ΔE-OK ×100Closest pair
Normal vision14.0 (≥ 11)2 and 6
Protanopia13.3 (≥ 11)1 and 5
Deuteranopia13.4 (≥ 11)2 and 6
Tritanopia12.8 (≥ 11)4 and 6

Why these colours

The selection method is the same as the larger categorical set: candidates that clear 3:1, then a search for the set with the largest smallest-pair distance over the four vision types. With only six colours, the optimiser has more room, and the accepted threshold is 11 instead of 8.

The resulting set mixes hue and lightness deliberately. Dichromats still see blue-yellow differences, and all viewers see lightness, so the set contrasts dark against light and blue against orange or brown, instead of relying on red-green. Achromatopsia, the rare case of no colour perception, is covered only by lightness and patterns, which is why the advice to add markers matters.

The generator solved 18 pairs (9 light, 9 dark), and all of them meet their target on the raw WCAG ratio. The tightest is series 5 on background in the light theme at 3.12:1 against a target of 3:1.

How to use it

  • Pair every colour with a second encoding: direct labels, marker shapes or dash styles.
  • Do not add a seventh colour; if you need more categories, group some or split into small multiples.
  • Avoid placing the two closest series next to each other where lines cross; use the table below to see which pair is closest under each simulation.
  • Show a legend in the same order as the data and test your chart with a colour-blindness simulator before shipping.
  • Provide a data table or text summary so the chart is not the only route to the numbers.

Chart advice

  • Prefer labelled lines and bars to legends the reader has to look up.
  • Use a thin background-coloured outline between stacked or adjacent fills.
  • Check the chart in grayscale as a quick extra test.

Export

Generated from the verified values above, never typed by hand. Light and dark are both included.

CSS custom properties (hex, then oklch())

/* sRGB hex first: every browser. */
:root {
  --color-background: #f9fcff;
  --color-text: #1d2022;
  --color-text-muted: #55585c;
  --color-axis: #83878b;
  --color-gridline: #ccd0d5;
  --color-series-1: #004b98;
  --color-series-2: #b48400;
  --color-series-3: #773000;
  --color-series-4: #9d6fe3;
  --color-series-5: #4c9e84;
  --color-series-6: #7d6622;
}
.dark {
  --color-background: #141618;
  --color-text: #e8ebef;
  --color-text-muted: #aeb1b6;
  --color-axis: #717579;
  --color-gridline: #33373a;
  --color-series-1: #86b8ff;
  --color-series-2: #cc5900;
  --color-series-3: #5a76e4;
  --color-series-4: #98b305;
  --color-series-5: #ffb5a8;
  --color-series-6: #a96988;
}

/* oklch() where supported: the same colours, unclipped values of the hex above. */
@supports (color: oklch(0 0 0)) {
  :root {
    --color-background: oklch(0.990 0.005 247.9);
    --color-text: oklch(0.241 0.006 236.8);
    --color-text-muted: oklch(0.459 0.008 255.5);
    --color-axis: oklch(0.621 0.008 247.9);
    --color-gridline: oklch(0.856 0.008 253.9);
    --color-series-1: oklch(0.421 0.142 255.6);
    --color-series-2: oklch(0.6433 0.1323 82.79);
    --color-series-3: oklch(0.403 0.112 46.6);
    --color-series-4: oklch(0.640 0.171 299.9);
    --color-series-5: oklch(0.640 0.090 170.2);
    --color-series-6: oklch(0.520 0.090 89.9);
  }
  .dark {
    --color-background: oklch(0.199 0.005 248.1);
    --color-text: oklch(0.939 0.006 255.5);
    --color-text-muted: oklch(0.760 0.008 260.7);
    --color-axis: oklch(0.560 0.008 248.0);
    --color-gridline: oklch(0.334 0.008 240.1);
    --color-series-1: oklch(0.775 0.115 257.2);
    --color-series-2: oklch(0.600 0.166 47.2);
    --color-series-3: oklch(0.600 0.169 269.9);
    --color-series-4: oklch(0.7206 0.1701 119.98);
    --color-series-5: oklch(0.839 0.089 30.2);
    --color-series-6: oklch(0.600 0.091 349.7);
  }
}

Tailwind CSS v4 @theme

@theme {
  /* light */
  --color-background: oklch(0.990 0.005 247.9); /* #f9fcff */
  --color-text: oklch(0.241 0.006 236.8); /* #1d2022 */
  --color-text-muted: oklch(0.459 0.008 255.5); /* #55585c */
  --color-axis: oklch(0.621 0.008 247.9); /* #83878b */
  --color-gridline: oklch(0.856 0.008 253.9); /* #ccd0d5 */
  --color-series-1: oklch(0.421 0.142 255.6); /* #004b98 */
  --color-series-2: oklch(0.6433 0.1323 82.79); /* #b48400 */
  --color-series-3: oklch(0.403 0.112 46.6); /* #773000 */
  --color-series-4: oklch(0.640 0.171 299.9); /* #9d6fe3 */
  --color-series-5: oklch(0.640 0.090 170.2); /* #4c9e84 */
  --color-series-6: oklch(0.520 0.090 89.9); /* #7d6622 */
  /* dark: use as dark:bg-background-dark, or remap under a .dark selector */
  --color-background-dark: oklch(0.199 0.005 248.1); /* #141618 */
  --color-text-dark: oklch(0.939 0.006 255.5); /* #e8ebef */
  --color-text-muted-dark: oklch(0.760 0.008 260.7); /* #aeb1b6 */
  --color-axis-dark: oklch(0.560 0.008 248.0); /* #717579 */
  --color-gridline-dark: oklch(0.334 0.008 240.1); /* #33373a */
  --color-series-1-dark: oklch(0.775 0.115 257.2); /* #86b8ff */
  --color-series-2-dark: oklch(0.600 0.166 47.2); /* #cc5900 */
  --color-series-3-dark: oklch(0.600 0.169 269.9); /* #5a76e4 */
  --color-series-4-dark: oklch(0.7206 0.1701 119.98); /* #98b305 */
  --color-series-5-dark: oklch(0.839 0.089 30.2); /* #ffb5a8 */
  --color-series-6-dark: oklch(0.600 0.091 349.7); /* #a96988 */
}

shadcn/ui variables (:root and .dark)

:root {
  --background: oklch(0.990 0.005 247.9);
  --foreground: oklch(0.241 0.006 236.8);
  --muted-foreground: oklch(0.459 0.008 255.5);
  --border: oklch(0.856 0.008 253.9);
  --input: oklch(0.621 0.008 247.9);
  --chart-1: oklch(0.421 0.142 255.6);
  --chart-2: oklch(0.6433 0.1323 82.79);
  --chart-3: oklch(0.640 0.171 299.9);
  --chart-4: oklch(0.640 0.090 170.2);
  --chart-5: oklch(0.520 0.090 89.9);
}

.dark {
  --background: oklch(0.199 0.005 248.1);
  --foreground: oklch(0.939 0.006 255.5);
  --muted-foreground: oklch(0.760 0.008 260.7);
  --border: oklch(0.334 0.008 240.1);
  --input: oklch(0.560 0.008 248.0);
  --chart-1: oklch(0.775 0.115 257.2);
  --chart-2: oklch(0.600 0.166 47.2);
  --chart-3: oklch(0.7206 0.1701 119.98);
  --chart-4: oklch(0.839 0.089 30.2);
  --chart-5: oklch(0.600 0.091 349.7);
}

Design tokens (DTCG-style JSON)

{
  "color": {
    "light": {
      "background": {
        "$type": "color",
        "$value": "oklch(0.990 0.005 247.9)",
        "$description": "sRGB #f9fcff"
      },
      "text": {
        "$type": "color",
        "$value": "oklch(0.241 0.006 236.8)",
        "$description": "sRGB #1d2022"
      },
      "text-muted": {
        "$type": "color",
        "$value": "oklch(0.459 0.008 255.5)",
        "$description": "sRGB #55585c"
      },
      "axis": {
        "$type": "color",
        "$value": "oklch(0.621 0.008 247.9)",
        "$description": "sRGB #83878b"
      },
      "gridline": {
        "$type": "color",
        "$value": "oklch(0.856 0.008 253.9)",
        "$description": "sRGB #ccd0d5"
      },
      "series-1": {
        "$type": "color",
        "$value": "oklch(0.421 0.142 255.6)",
        "$description": "sRGB #004b98"
      },
      "series-2": {
        "$type": "color",
        "$value": "oklch(0.6433 0.1323 82.79)",
        "$description": "sRGB #b48400"
      },
      "series-3": {
        "$type": "color",
        "$value": "oklch(0.403 0.112 46.6)",
        "$description": "sRGB #773000"
      },
      "series-4": {
        "$type": "color",
        "$value": "oklch(0.640 0.171 299.9)",
        "$description": "sRGB #9d6fe3"
      },
      "series-5": {
        "$type": "color",
        "$value": "oklch(0.640 0.090 170.2)",
        "$description": "sRGB #4c9e84"
      },
      "series-6": {
        "$type": "color",
        "$value": "oklch(0.520 0.090 89.9)",
        "$description": "sRGB #7d6622"
      }
    },
    "dark": {
      "background": {
        "$type": "color",
        "$value": "oklch(0.199 0.005 248.1)",
        "$description": "sRGB #141618"
      },
      "text": {
        "$type": "color",
        "$value": "oklch(0.939 0.006 255.5)",
        "$description": "sRGB #e8ebef"
      },
      "text-muted": {
        "$type": "color",
        "$value": "oklch(0.760 0.008 260.7)",
        "$description": "sRGB #aeb1b6"
      },
      "axis": {
        "$type": "color",
        "$value": "oklch(0.560 0.008 248.0)",
        "$description": "sRGB #717579"
      },
      "gridline": {
        "$type": "color",
        "$value": "oklch(0.334 0.008 240.1)",
        "$description": "sRGB #33373a"
      },
      "series-1": {
        "$type": "color",
        "$value": "oklch(0.775 0.115 257.2)",
        "$description": "sRGB #86b8ff"
      },
      "series-2": {
        "$type": "color",
        "$value": "oklch(0.600 0.166 47.2)",
        "$description": "sRGB #cc5900"
      },
      "series-3": {
        "$type": "color",
        "$value": "oklch(0.600 0.169 269.9)",
        "$description": "sRGB #5a76e4"
      },
      "series-4": {
        "$type": "color",
        "$value": "oklch(0.7206 0.1701 119.98)",
        "$description": "sRGB #98b305"
      },
      "series-5": {
        "$type": "color",
        "$value": "oklch(0.839 0.089 30.2)",
        "$description": "sRGB #ffb5a8"
      },
      "series-6": {
        "$type": "color",
        "$value": "oklch(0.600 0.091 349.7)",
        "$description": "sRGB #a96988"
      }
    }
  }
}

Open in the studio

Take the first series colour into the picker, build a tonal scale from it, or check any pair of your own.

Open #004B98 in the OKLCH picker →Build a tonal scale →Check a pair

FAQ

How is this different from the eight-colour palette?
It has fewer colours and a higher threshold, 11 instead of 8, so every pair is further apart. The eight-colour set maximises count; this one maximises separation.
Does it work for achromatopsia?
Only partly. The colours differ in lightness, but with no colour perception similar-lightness pairs can merge. Patterns and labels are the dependable answer. The colour blindness page previews a text and background pair in luminance only.
Can I use it for maps?
For categorical map regions, yes, up to six classes. For values that increase, use the sequential palette.
Is the Machado simulation accurate?
It is a widely used model of dichromacy, not a measurement of any one person's vision. Treat the numbers as a strong screening signal.

← All accessible palettes