Google Summer of Code '24: Color Unclasher

A CLI and JavaScript utility that helps MapLibre style authors make their maps more accessible for people with color blindness by analyzing color pairs with DeltaE.
ReactJavaScript

Project Type

Open-source tooling

My Role

Creator

Current Status

Published on npm

What Color-Unclasher Does

Color-Unclasher is designed to help developers make their MapLibre styles more accessible to users with different types of color blindness. It analyzes color combinations within a style specification and reports any non-compliant layer pairs.

For each pair of layers at the same zoom level, the tool simulates how their colors look under different types of color blindness and computes their DeltaE (CIE 2000) difference. If the DeltaE is below a minimum threshold, that pair is flagged as non-compliant.

Results can be written out as a human-readable report (to the terminal or a file) and/or as structured JSON that you can feed back into future analyses.

Color Perceptions Considered

Color-Unclasher simulates multiple types of color vision to ensure that map styles work for as many people as possible.

NameTypeCause
Normal VisionNo color blindnessHas red, green, and blue cones
ProtanopiaRed–Green color blindnessMissing red cone
DeuteranopiaRed–Green color blindnessMissing green cone
TritanopiaBlue–Yellow color blindnessMissing blue cone

Why DeltaE?

DeltaE (CIE 2000) is a metric for how humans perceive color difference. A value of 0 means no difference, and 100 represents the maximum perceivable difference. Color-Unclasher uses chroma.js's deltaE implementation, based on Bruce Lindbloom's formula.

Many accessibility checks rely on WCAG color contrast ratio, which is ideal for text on a background. But map tiles often cover similar areas of the screen. Two tiles such as #475C5C and #515062 might fail traditional contrast ratio checks while still being visually distinguishable as map regions. DeltaE lets us express that nuance.

Supported & Unsupported Expressions

Supports

  • steps
  • stops
  • interpolate
  • interpolate with a single layer of match
  • case

Not Supported (Yet)

  • Nested match expressions
  • in expressions
  • Other complex, deeply nested expressions

Recommendations

  • Use editor extensions that render inline color previews (e.g., Color Highlight in VS Code) so you can see color changes as you edit your MapLibre style JSON.
  • Experiment with different minimum DeltaE values and preview colors using leonardocolor.io. The pair #475C5C and #515062 has DeltaE values of 5.56 (Deuteranopia), 7.95 (Protanopia), and 6.46 (Tritanopia).
  • Explore how groups of colors behave for different types of color blindness via Adobe Color's accessibility tools.

Example Workflow

A typical workflow is to run an analysis, export non-compliant pairs, curate which ones you care about, and then re-run the analysis with an ignore list.

# 1. Export non-compliant pairs
color-unclasher styles.json result.txt --export-pairs-path output.json

# 2. Manually edit output.json to keep only the pairs you want to ignore,
#    for example, leaving only ["airport", "grass"] for a given zoom level.

# 3. Re-run the analysis with the ignore list
color-unclasher styles.json result.txt --pairs-to-ignore-path output.json

The second run will skip any pairs you've configured to ignore, so the report focuses on the remaining issues.

API: Get Adjusted Colors

Behind the scenes, Color-Unclasher can suggest alternative colors that meet your minimum DeltaE threshold using adjustRGB and adjustHSL. These utilities incrementally adjust red, green, blue or hue, saturation, and lightness to discover compliant candidates.

import ColorUnclasher from "color-unclasher";

const color1 = "#a4a95b"; // fixed
const color2 = "#ff8375"; // to be adjusted
const mode = "deuteranopia"; // protanopia | deuteranopia | tritanopia
const minDeltaE = 7;

const suggestions = ColorUnclasher.adjustRGB(color1, color2, mode, minDeltaE);

// suggestions might include keys like:
//   red_increase, red_decrease,
//   green_increase, green_decrease,
//   blue_increase, blue_decrease

In the CLI, automatic suggestions start by trying colors with increased red (for RGB) or increased hue (for HSL), so there is a slight bias toward those directions. When using the API directly, you can inspect all suggested colors and pick the one that best fits your visual language.