Google Summer of Code '24: Color Unclasher


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.
| Name | Type | Cause |
|---|---|---|
| Normal Vision | No color blindness | Has red, green, and blue cones |
| Protanopia | Red–Green color blindness | Missing red cone |
| Deuteranopia | Red–Green color blindness | Missing green cone |
| Tritanopia | Blue–Yellow color blindness | Missing 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
stepsstopsinterpolateinterpolatewith a single layer ofmatchcase
Not Supported (Yet)
- Nested match expressions
inexpressions- 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
#475C5Cand#515062has 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.