color theory

Lightness Drift

Lightness drift is the perceptual mismatch that occurs in sRGB based color systems where colors assigned the same numeric lightness value appear at noticeably different brightness levels to the human eye. It is the reason your blue-300 and your yellow-300 never feel like they belong on the same step of the ramp. The math says equal. The eye says no. This drift stems directly from the fact that hex and HSL are built on top of sRGB which was engineered for 1990s CRT monitors rather than human vision. The luminance formula in sRGB weights the green channel at 0.7152 the red at 0.2126 and the blue at a measly 0.0722. A full intensity green therefore contributes ten times more to perceived brightness than full intensity blue. When you set hsl(240 100% 50%) against hsl(60 100% 50%) the yellow destroys the blue in visual weight. Your carefully constructed system falls apart at scale.

Lightness drift is not a design taste issue. It is not something fixed by better calibration or by asking for feedback in more design critiques. It is not solved by manually adjusting each hue until it looks right on your particular monitor. Those fixes are temporary and brittle. They break on customer devices. They break in dark mode. They break when new hues get added to the palette. Lightness drift is a hard limitation of the color space. HSL gave the illusion of control with its dedicated lightness channel. That channel still maps back to the same flawed sRGB math. The promise was perceptual control. The delivery was marketing speak layered on top of 1996 technology.

A concrete example sits in the 2020 Material Design color system from Google. Their blue 500 at #4285f4 was paired with an amber 500 at #ffc107. Both claimed similar lightness positions in their documentation. In practice the amber read significantly lighter and more energetic. This caused constant tension in UI components where primary and accent colors needed to feel balanced. Android app developers complained about it in forums for years. The same drift appeared in their dark mode variants where certain status colors failed contrast checks while their neighbors passed. Google eventually started moving toward more perceptual models in later Material You updates.

Another concrete example comes from the design system at Stripe in 2022. During their checkout redesign the team set their brand blue and their accent orange at what they thought were equivalent steps. On launch day the orange buttons looked far more prominent than the blue ones. User testing revealed customers noticed the imbalance even if they could not name why. The engineering team spent three additional sprints creating custom overrides for dark mode and hover states. All of that work could have been avoided with a perceptually uniform space like OKLCH. Similar stories played out at companies like Dropbox and Notion in the same time period. Their color ramps required constant maintenance because the drift kept introducing visual hierarchy problems no one had budgeted time to fix. In one audit a blue-300 sat at L=0.72 in OKLCH terms while the matching yellow-300 sat at L=0.87. That 0.15 difference is massive in perceived brightness. It is the difference between a color that sits back and one that jumps forward. The Tailwind v3 palette showed the same flaw with blue-500 at hsl(217 91% 60%) and amber-500 at hsl(38 92% 50%). The amber floated while the blue sank creating chaos in data tables and status indicators.

Watch for lightness drift and fight it when you are building design systems meant to last more than 12 months. Watch for it when your palette serves both light and dark modes. Watch for it when more than three hues are in play or when more than five engineers touch the token file. These conditions turn drift from a minor annoyance into a recurring tax on velocity. Do not bother fighting it when you are shipping a single page marketing site that uses a hero color and two neutrals. Do not bother when the project is a one week experiment or a personal portfolio. The migration effort exceeds the benefit in those cases. Know your context. Spend the heavy lifting on systems that will compound.

OKLCH changes the equation completely. Its lightness value is calibrated to human vision. L equals 0.75 means the same thing for every hue. Blue 300 and yellow 300 now share real visual weight instead of approximate. Gradients flow naturally without muddy middles. Dark mode becomes a formula instead of a series of hard coded exceptions. Contrast prediction gets easier because the L value actually correlates with the luminance the accessibility checkers care about. Teams at Tailwind CSS made this exact move in version 4 released in 2024. Radix UI updated their primitives to use similar perceptual scales. The results speak for themselves. Palettes that hold their structure. Fewer bugs. Faster iteration.

Lightness drift is the hidden reason your color system keeps demanding manual tweaks and why switching to OKLCH feels like the cheat code nobody told you about until now.

Related terms

Keep exploring