Colorblind by Default: How to Build a 5-Color UI Palette That Works for Everyone Without Looking Like a Safety Manual
Updated

Colorblind by Default: How to Build a 5-Color UI Palette That Works for Everyone Without Looking Like a Safety Manual

by Julio Song

Roughly 1 in 12 men and 1 in 200 women have some form of color vision deficiency. On a typical SaaS product with 50,000 users, that means thousands of people are working around your UI every day. They're squinting at status badges, guessing which form field triggered an error, and mentally compensating for charts that look like a wall of identical gray bars.

Most "accessible palette" tutorials respond by draining the personality out of their color choices. You end up with something that looks like the liability department designed it. It's technically compliant and nobody in a stakeholder review will like it.

It doesn't have to go that way. Handled well, the constraint works more like a design brief. This post walks through a repeatable 5-step system for a palette that passes WCAG 3.0 contrast requirements, accounts for all four major types of color vision deficiency, and still looks like something a design team would ship. You pick a primary hue, build outward from it, test against real components, and end up with a palette that has some character.

Why the stakes changed in 2025 and 2026 (and why most palettes still fail)

Regulation has moved fast. The EU Accessibility Act began enforcement in 2025, WCAG 3.0 draft guidance on non-text contrast and the APCA contrast model gained serious traction heading into 2026, and US state-level legislation like California's AB 1757 has added legal pressure beyond the ADA. If your product ships in a major market, accessibility is no longer optional.

But regulation alone doesn't tell you how to design well. To do that, you need to understand what you're designing for.

There are four main types of color vision deficiency:

  • Deuteranopia (red-green, most common): affects roughly 6% of men
  • Protanopia (red-green, less common): affects about 1% of men
  • Tritanopia (blue-yellow, rare): affects fewer than 0.01% of the population
  • Achromatopsia (full monochromacy, very rare): complete absence of color perception

The hard part is designing for all four at once. Most tutorials fall into one of two failure modes. The first strips saturation until the palette is universally legible but visually dead. The second tests for one type of CVD (usually deuteranopia, since it's the most common) and leaves the other three unaddressed.

The rest of this article builds on one observation. Because the constraints across all four CVD types partially overlap, a well-chosen primary hue can satisfy all of them and still leave plenty of room for visual personality.

Side-by-side comparison of a SaaS dashboard in normal vision versus deuteranopia simulation, showing how red and green UI elements become nearly indistinguishable under red-green color vision deficiency.

The screenshot above shows how much information can vanish under a single CVD simulation. Now multiply that across four types, and you start to see why "just check the contrast ratio" isn't enough.

Step 1: Choose a primary hue that doesn't fight you

Hue selection is the decision that affects everything downstream. Some hues hold up under CVD better than others. Blues and blue-violets are the most distinguishable across all CVD types, and warm yellows and oranges make strong secondaries. Pure reds and pure greens cause the most trouble.

The concept you need here is hue shift under simulation. Every color looks different when viewed through a CVD simulation. A vivid red might shift to a muddy olive under deuteranopia. A bright green might become indistinguishable from a beige under protanopia. Before you commit to a primary, you need to run it through all three chromatic simulations (deuteranopia, protanopia, and tritanopia) and check whether it retains its identity.

Here's an example. Take a blue-teal primary at HSL 195°, 70%, 45%. Under deuteranopia, it shifts slightly but remains clearly blue. Under protanopia, same story. Under tritanopia, it darkens a touch but stays recognizable. Under achromatopsia, it renders as a medium gray with enough lightness distinction to work against light and dark neutrals. This hue survives all four simulations with its identity intact.

A few tools make this quick: the ColorSift colour blindness simulator for checking a palette against eight types of deficiency, Coblis for uploading full screenshots, Adobe Color's accessibility panel, the Figma plugin "Color Blind" for in-canvas simulation, and the APCA Contrast Calculator at contrast.wtf for scoring against the updated WCAG 3.0 model.

Rule of thumb: your primary hue should not shift more than 30° of perceived hue under any CVD simulation. If it does, treat that as a warning sign and adjust before building the rest of the system.

Step 2: Build the supporting four, contrast-safe from the start

Here's the 5-color palette structure you're building:

  1. Primary (brand identity, key actions)
  2. Neutral (text, backgrounds, borders)
  3. Accent (interactive states, highlights)
  4. Semantic: Success (confirmation, positive states)
  5. Semantic: Warning/Error (alerts, destructive actions)

That's the smallest set a real UI system can get by with. Here's how to build each one.

The neutral. Pure gray is safe but bland. A slightly warm or cool neutral gives personality without creating CVD risk. Derive it from your primary hue's color temperature. For our blue-teal primary, that means a blue-tinted near-white (#F4F7F9) for backgrounds and a blue-tinted near-black (#1A2332) for text. The tint is subtle enough to pass unnoticed consciously, but it creates cohesion.

The accent. You need something distinguishable from the primary under all CVD simulations. A yellow-orange at roughly HSL 38°, 85%, 55% pairs well with a blue-teal primary because it sits on the opposite side of the CVD-safe spectrum. Even under achromatopsia, the lightness difference between a medium-dark teal and a bright yellow-orange keeps them distinct. The APCA contrast score for this pairing against the dark neutral clears Lc 60 comfortably.

The semantic colors, the hardest part. Most designers default to green for success and red for error, which is exactly the pairing that fails for red-green CVD. You don't have to give up the meaning. Instead, replace hue-only differentiation with a triple-redundant system: hue + lightness + icon/shape.

For the semantic pair, consider teal-green (HSL 160°, 55%, 40%) for success and amber-orange (HSL 30°, 80%, 50%) for warning/error. The teal-green is shifted far enough from pure green to survive deuteranopia. The amber-orange stays out of pure-red territory. They also differ by roughly 25 lightness points, so they remain distinct even in full monochromacy.

Ming#1a7f8f
Cultured#f4f7f9
Dark Gunmetal#1a2332
Tiger's Eye#d9922a
Illuminating Emerald#2d8a6b
Bronze#cc7a2e

Five-color UI palette displayed in normal vision and simulated through all four types of color vision deficiency, demonstrating that the colors remain distinguishable across deuteranopia, protanopia, tritanopia, and achromatopsia.

Step 3: Test against real UI components (the part most tutorials skip)

A palette that passes abstract contrast checks can still fail badly in a real UI. CVD failures tend to hide in buttons with hover states, data visualizations, form validation, toast notifications and disabled states.

Buttons. Take a primary-fill button with a white label. The hover state darkens the fill by 10%. The focus ring is a 3px blue outline. Under tritanopia, that blue focus ring can become nearly invisible against a light background. Fix: add a secondary dark outline or increase the contrast differential to at least Lc 45 against the surrounding area.

Form validation. The classic failure: red border + red icon + red helper text. Under deuteranopia, all three signals collapse into a muddy brownish tone that barely registers as "error." The triple-redundancy approach solves it: use amber-orange for the color channel, a warning triangle icon for the shape channel, and bold underlined text for the typography channel. Each of those three signals works on its own. The result also looks better, because the user has more ways to read the state quickly.

Data charts. Two bars in a simple bar chart might look distinct in normal vision but merge into near-identical grays under achromatopsia. WCAG 3.0 recommends pattern and texture fills alongside color. Hatching, dots, or diagonal lines give each series its own look that holds up even on a black-and-white printout. It doesn't have to be ugly: Stripe uses patterned charts in its dashboard and they look good.

Three UI components demonstrating triple-redundancy accessibility: a button with a visible focus ring, a form field with icon and color error state, and a bar chart using both color and pattern fills to distinguish data series.

Case study: two palettes, one system

The method isn't tied to one look. Here it is run twice with very different personality targets.

Palette A: Calm Authority (fintech/enterprise)

Built around a deep blue-indigo primary at HSL 225°, 55%, 38%. The neutral pair is a cool off-white (#F0F2F5) and charcoal (#1E2433). The accent is a muted gold (#B8963E). Semantic colors: slate-teal (#3A7D7E) for success, amber (#C67A2E) for warning. Every swatch survives all four CVD simulations. The APCA score for charcoal text on the off-white background hits Lc 92.

St. Patrick's Blue#2e3f6e
Anti-Flash White#f0f2f5
Dark Gunmetal#1e2433
Brass#b8963e
Ming#3a7d7e
Bronze#c67a2e

Palette B: Warm Energy (consumer wellness)

Primary: blue-teal at HSL 188°, 65%, 42%. Neutral: warm cream (#FBF6EF) and near-black with a warm undertone (#2A2420). Accent: sunflower yellow-orange (#E8A624). Semantic pair: medium teal-green (#2E9E7A) for success, deep orange (#D4652A) for warning. The logic is the same and the mood is completely different. All CVD simulations pass.

Illuminating Emerald#1e8a8a
Seashell#fbf6ef
Raisin Black#2a2420
Marigold#e8a624
Illuminating Emerald#2e9e7a
Chocolate (Web)#d4652a

Both palettes come from the same system, both are compliant, and you could ship either one.

The non-color layer

The broader principle is that color should never be the only channel for information in a UI. WCAG 3.0 makes this explicit: no information conveyed by color alone.

These non-color signals work alongside a CVD-safe palette:

  • Iconography and shape: a warning triangle versus a check circle communicates state before color even registers
  • Typography weight and style: bold error labels versus normal-weight success labels create a visual hierarchy independent of hue
  • Motion and position: error fields that briefly shake, inline helper text that appears below the field, toast notifications that animate in from a consistent direction

These signals help more people than just users with CVD. They also help anyone in bright sunlight, on a low-quality screen, under cognitive load, or skimming.

Start by auditing your current UI for any component where color is the only differentiator. The usual offenders:

  • Status badges: Add a text label or icon inside the badge
  • Data charts: Add pattern fills or direct labels to each series
  • Form states: Add an icon and a text label alongside the color change

A CVD-safe palette in light mode is not automatically safe in dark mode. Lightness inversion can destroy contrast ratios. When you build your dark variant, re-check every APCA score. The relationship between your semantic colors and your dark background may need manual adjustment.

Where to start

Those thousands of users working around your UI are still there, and now you have a system for designing with them in mind.

A CVD-safe, WCAG 3.0-compliant system does more than tick a compliance box. The interface ends up more legible for everyone who uses it. The safety-manual look isn't the price of accessibility. You get it when accessibility is treated as a constraint to minimize instead of a brief to solve.

Take the palette values from either case study above, run your current UI through a CVD simulator this week, and find the component that fails worst. Fix that one first.