Most UI kits ship with five or six avatar colors and call it diversity. Anyone who has tried to implement a genuinely inclusive skin tone selector — for a social app, a healthcare platform, or a video-calling product — knows how quickly that assumption falls apart. The problem is not just aesthetic; it sits at the intersection of color science, perceptual psychology, and product ethics.

Why "Just Add More Colors" Does Not Work

The naive approach is to pick a handful of hex values that look different on a monitor and call it done. The trouble is that human skin tones vary along multiple dimensions simultaneously: hue (yellow, red, olive, cool brown), saturation, and lightness. A flat list of swatches sampled by eye tends to cluster around the most "visible" tones and leave large perceptual gaps — typically at the lighter and darker extremes.

Two failure modes appear constantly in production:

  • Perceptual bunching — several swatches look nearly identical under different display calibrations or ambient lighting conditions.
  • Representational gaps — entire populations simply cannot find themselves in the palette.

Neither failure is caught by standard accessibility audits, which focus on contrast ratios between text and background, not on the internal diversity of a palette.

Color Spaces Matter More Than People Think

RGB is convenient for rendering, but it is a terrible space for designing a palette that feels perceptually uniform. When you move equal numerical distances in RGB space, the perceived difference between two colors is wildly inconsistent. The same is true of HSL.

The color science community has long relied on perceptually uniform spaces for exactly this kind of work:

  • CIELAB (L*a*b*) — separates lightness from chromatic axes. Equal Euclidean distances correspond to roughly equal perceived differences.
  • CIELUV — a close cousin, better suited for self-luminous displays.
  • Oklab — a modern, computationally friendly approximation that has gained traction in CSS and design tooling.

The core insight behind any rigorous skin tone algorithm is to sample a path through perceptual color space, not through RGB. You define a curve or segment in L*a*b* (or a similar space) that passes through the hue angles and lightness ranges associated with human skin, then distribute your palette points along that curve at equal perceptual intervals.

import numpy as np
from colormath.color_objects import LabColor, sRGBColor
from colormath.color_conversions import convert_color

def sample_skin_tone_path(n_swatches=12):
    """
    Sample n points along a perceptual path through CIELAB
    that approximates the human skin tone gamut.
    L: 25 (deep) to 90 (very light)
    a: 5 to 20 (reddish)
    b: 10 to 30 (yellowish)
    """
    t = np.linspace(0, 1, n_swatches)
    L = 25 + t * 65      # lightness ramp
    a = 20 - t * 15      # redness decreases slightly toward lighter tones
    b = 30 - t * 20      # yellowness decreases toward lighter tones

    swatches = []
    for L_val, a_val, b_val in zip(L, a, b):
        lab = LabColor(L_val, a_val, b_val)
        rgb = convert_color(lab, sRGBColor, target_illuminant='d65')
        swatches.append(rgb.get_value_tuple())
    return swatches

This is a simplified illustration. Real implementations add gamut-clamping (some Lab coordinates map outside sRGB), blue-undertone variants for cooler skin tones, and optional randomization within a bounding volume to avoid a palette that feels mechanical.

Algorithmic Generation vs. Curated Palettes

There is a genuine tension here. Algorithmically generated palettes offer consistency and scalability — you can parameterize the curve and produce 8, 16, or 64 swatches on demand. But they carry a risk: the algorithm encodes the assumptions of whoever defined the path through color space. If that person's mental model of "skin tones" is narrow, the output will be too.

Curated palettes — the approach taken by standards like the Unicode Emoji skin tone modifiers (based loosely on the Fitzpatrick scale) — benefit from deliberate human judgment and community feedback. The Fitzpatrick scale itself was designed for dermatological research, not UI design, which is why it maps awkwardly onto the full range of human complexions when used as a direct palette source.

The practical answer for most teams is a hybrid: use a perceptually uniform color space to generate candidate swatches algorithmically, then have a human review pass — ideally involving people from a range of backgrounds — to catch gaps and remove mechanical-feeling clusters.

What This Means for Product and Platform Teams

If your product involves user avatars, profile customization, health or wellness inputs (e.g., skin condition tracking), or any generative imagery, these considerations are not optional polish. They are core to whether underrepresented users feel the product was built with them in mind.

A few concrete recommendations:

  • Use Oklab or CIELAB as your working space when building or auditing a skin tone palette. Convert to sRGB only at the point of rendering.
  • Test your palette under multiple display profiles — sRGB, P3, and standard monitor gamma — because a palette that looks diverse on a calibrated designer's display can collapse on a cheap laptop screen.
  • Document your palette's design rationale, including the color space used and the criteria for swatch selection. This makes future updates principled rather than ad hoc.
  • Involve diverse reviewers early, not as a final sign-off gate but as an input to the design loop.
  • Separate the palette from the UI affordance. A well-designed 16-swatch palette presented in a confusing picker is still a bad user experience.

Representation as Engineering Quality

It is tempting to frame inclusive design as a values question separate from engineering quality. In practice, the two are inseparable. A skin tone selector built on perceptual color science is also a more correct implementation — it makes fewer arbitrary assumptions, fails more gracefully across display environments, and requires fewer ad hoc patches as you expand to new markets.

The same principle applies broadly: building for a wider range of users tends to surface edge cases that improve robustness for everyone. Inclusive engineering is not a tax on velocity; it is a forcing function for doing the underlying work properly.

Source: Toney Alexander, "Inclusive Color Space" — https://toneyalexander.github.io/inclusive-color-space/


Why this matters for your project: Whether you are building a consumer social platform, a telemedicine app, or an enterprise HR tool with profile features, the moment you render a human face or avatar you are making a representation decision. Getting the color science right from the start — using perceptually uniform spaces, algorithmic generation, and diverse human review — is far cheaper than retrofitting a broken palette after launch, especially when your user base spans multiple continents.