Why Your Color Palette Looks Wrong
Evenly-spaced colors don't look even because RGB and HSL don't match human perception. Learn how perceptual color spaces fix this problem.
You are working on a design project. You pick a blue, generate a palette from it — lightest to darkest, evenly spaced. Everything should be perfect. But when you look at the screen, something is off: some steps feel huge, others barely visible. The colors are mathematically even, but they definitely do not look even to your eyes.
In this post, we will explain why this happens, what causes it, and how to fix it.
The Problem Everyone Experiences
Let's say you want to create a 5-step palette from a shade of blue. The easiest approach: take the HSL color model and increase the lightness value in equal steps. 10, 30, 50, 70, 90. Mathematically, a perfect distribution.
But when you look at the result, you see something like this:
In the top palette, the dark tones feel miles apart while the light tones look almost identical. In the bottom palette, every step feels even. Both are 5 steps — but one looks right to your eyes and the other does not.
Why?
The Culprit: RGB and HSL
Computers represent colors with numbers. The two most common systems are RGB (red-green-blue) and HSL (hue-saturation-lightness). These models are designed to describe how screens work — your pixels literally emit red, green, and blue light.
But here is the critical detail: how your screen works and how your eye works are not the same thing.
In RGB, the mathematical distance between two colors is always calculated with the same formula. Say you darken a shade of blue by one step and darken a shade of yellow by the same amount. The math says "both changes are equal." But your eye disagrees.
HSL does not solve this either. HSL is just a different representation of RGB — the same data in different packaging. Since the underlying math has not changed, the perceptual problems remain exactly the same.
Why the Human Eye Perceives Differently
The retina in your eye contains three types of color-sensing cells (cone cells): ones sensitive to red, green, and blue light. But these three types are not distributed equally, and they are not equally sensitive.
- We are most sensitive to green. About 70% of our brightness perception comes from green cone cells.
- Red is moderate. It contributes roughly 21% to brightness perception.
- We are least sensitive to blue. Blue contributes only about 7% to brightness perception.
What does this mean? If you make a small change to a green color, your eye notices it immediately. But if you make the same-sized change to a blue color, you barely notice it at all.
And it is not just about brightness. Our eyes distinguish differences in dark tones much more easily than in light tones. Moving from dark to slightly darker feels like a huge jump; moving from light to slightly lighter feels like almost nothing — even when the numerical change is identical.
There is also the Helmholtz-Kohlrausch effect: vivid, saturated colors appear brighter than they actually are. Place a bright red next to a gray with the same physical luminance, and the red will look lighter. This means that even matching brightness alone is not enough.
What Is Perceptual Uniformity?
Let us explain this concept as simply as possible.
Think of a ruler. The centimeter markings on a ruler are equally spaced in the real world — the physical distance between 1 cm and 2 cm is the same as between 8 cm and 9 cm. Your ruler is a "uniform" measuring tool.
Now imagine a ruler where the markings are not equally spaced: the first few centimeters are squeezed close together, and each subsequent mark gets farther and farther apart. This ruler is "non-uniform" — the distance between 1 and 2 is very different from the distance between 8 and 9.
RGB and HSL are like a broken ruler. The numbers may be equally spaced, but the perceptual distances they represent are not. A 10-unit difference can sometimes look enormous and sometimes be nearly invisible.
A perceptually uniform color space is like a proper ruler. In such a space, a 10-unit distance looks the same to your eyes no matter where you are in the color space. A 10-unit difference between two dark blues is just as noticeable as a 10-unit difference between two light yellows.
The Fix: Use a Perceptual Color Space
The solution is straightforward: when building palettes, use a perceptually uniform color space instead of RGB or HSL.
There are several options in this area:
- CIE Lab — Designed in 1976. The first attempt at a perceptually uniform space, but it makes significant errors with vivid colors.
- Oklab — Modern and part of the CSS standard. A good approximation with 18 parameters, but it cannot model certain visual phenomena.
- Helmlab — Built on over 64,000 human experiments, with 72 parameters and a 13-stage transform. The most accurate alternative available today.
The accuracy of these spaces is measured by a metric called STRESS. STRESS tells you how closely a color space's predictions match actual human perception. Lower is better:
- CIE Lab: ~30.3
- Oklab: ~27.5
- CIEDE2000 (industry standard formula): 29.2
- Helmlab: 23.2
Helmlab is 20% more accurate than the industry standard CIEDE2000 and 16% more accurate than the modern CSS standard Oklab. This is not a theoretical difference — it produces visibly better results when generating palettes, calculating contrast, and creating color transitions.
Helmlab's Edge: 64,000 Human Observations
Many color spaces are designed based on mathematical assumptions or physical measurements. Helmlab takes a different approach: it asks humans.
Behind Helmlab are over 64,000 human color-difference observations. These experiments work like this: people are shown pairs of colors and asked "How different do these two colors look?" Thousands of people answer this question for thousands of color pairs.
Helmlab's 72 parameters are optimized against this massive human dataset. The goal: minimize the gap between the distances Helmlab calculates and the distances humans actually perceive. The result is a color space that matches human vision more closely than any alternative.
This approach gives Helmlab some unique capabilities. It directly models the Helmholtz-Kohlrausch effect (vivid colors appearing brighter). It handles perception differences in dark and light tones separately. It applies different calibrations for different hue regions (reds, blues, greens).
In Practice: Building a Palette with Helmlab
Helmlab is available as an npm package — 10KB, zero dependencies:
npm install helmlabCreating a Tailwind CSS-style 11-step scale from a shade of blue is this simple:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Generate a semantic scale from a blue
const scale = hl.semanticScale('#3B82F6');
// Result: 11 shades with perceptually equal spacing
// {
// '50': '#b3c7ff', // lightest
// '100': '#aabdff',
// '200': '#96aaff',
// '300': '#809aff',
// '400': '#6089f8',
// '500': '#3b82f6', // base color
// '600': '#2e64c4',
// '700': '#224994',
// '800': '#163067',
// '900': '#0b1a3d',
// '950': '#070f28', // darkest
// }Every step in this palette has the same perceptual distance. The jump from 50 to 100 looks just as noticeable to your eyes as the jump from 800 to 900.
If you want to measure the perceptual distance between two colors:
// How different do two colors look?
const diff = hl.deltaE('#3B82F6', '#2563EB');
// → larger number = more noticeable differenceYou can also access a color's Lab coordinates directly:
// Convert a color to Helmlab Lab space
const lab = hl.fromHex('#3B82F6');
// → [L, a, b]
// L = lightness, a = red-green axis, b = yellow-blue axis
// Convert Lab back to hex
const hex = hl.toHex([0.5, -0.1, 0.2]);
// → '#rrggbb'Conclusion
If your palette looks wrong, the problem is not your aesthetic sense — it is your tools. RGB and HSL speak the language of screens, not the language of the human eye. When you make your color choices, palettes, and transitions in a perceptually uniform space, the results will always look more natural and consistent.
Helmlab, built on 64,000 human observations and the most accurate alternative available today, fills this gap. You can add it to your project with a 10KB npm package and start using it right away.
npm install helmlabMake your palettes not just mathematically correct, but perceptually correct too.