You send a design to a colleague. Same HEX code, same browser, and on their screen the blue is noticeably flatter than on yours. Nobody made a mistake. A HEX code is not a color — it is an instruction, and different displays follow it differently.

Understanding why saves a lot of pointless back-and-forth, and it changes how much precision is worth chasing.

A HEX code is a set of instructions, not a color

#3B82F6 says: drive the red subpixel to 59, the green to 130, the blue to 246. It says nothing about what those intensities should look like. That depends entirely on the physical display — how bright its backlight is, what wavelengths its filters pass, how it is calibrated.

A color space is the missing half of the instruction. It defines what "maximum red" actually means, as a real coordinate in human vision. Give the same numbers to two displays using different color spaces and you get two visibly different colors, both technically correct.

sRGB and the wide-gamut displays that broke the assumption

For roughly two decades the web had a comfortable default: everything was sRGB. It was standardised in 1996 around the capabilities of the CRT monitors of the day, and because almost every display could manage roughly that range, the web could ignore the whole problem.

That assumption is gone. Modern phones, laptops and monitors increasingly ship with wide-gamut panels — commonly Display P3, which covers noticeably more of the visible spectrum, particularly in reds and greens. These displays can show colors that simply do not exist in sRGB.

This is good news that creates a new failure mode. If a wide-gamut display treats an sRGB value as if it were in its own larger space, every color gets stretched outward and the whole design looks oversaturated. Well-behaved systems handle this correctly with color management. Not every path through a browser, an operating system and a screenshot tool is well-behaved.

Where the differences actually come from

Panel technology. An OLED renders black by switching pixels off entirely, so its contrast is effectively unlimited. An LCD leaks backlight through, producing a dark gray. A dark UI that looks rich on OLED can look washed out on a budget LCD, without a single value changing.

Brightness and ambient light. Perceived contrast changes with surroundings. The same screen in a bright room shows visibly less shadow detail than in a dim one, which is why a subtle border that reads clearly at your desk can vanish outdoors.

Calibration and factory variance. Two units of the same monitor model differ. Uncalibrated consumer displays commonly run cool, warm, or simply too bright, and most people never adjust them.

Operating system color settings. Night-shift and blue-light modes actively warp the color of everything on screen. So do accessibility filters and per-app color profiles.

Browser handling. Browsers differ in how they treat untagged images and how they map colors on wide-gamut screens. Most of the time this is invisible; occasionally it produces a real difference between two browsers on the same machine.

Why an image can disagree with a CSS value

A common and confusing case: a logo PNG placed next to a CSS background set to the same HEX, and the two do not match.

The usual cause is an embedded color profile. The image carries a tag saying "interpret my numbers in Adobe RGB", the browser dutifully converts them for display, and the converted result no longer equals the raw CSS value — which is always interpreted as sRGB.

The fix is to convert the image to sRGB when exporting it, which every design tool offers. If your logo has ever looked subtly wrong against its own brand color, this is the first place to look.

What this means for how precisely you work

The honest conclusion is that pixel-perfect color reproduction across every user's screen is not achievable. That is not defeatism — it is a useful constraint, because it tells you where precision pays and where it does not.

Precision matters for relationships. Contrast ratios, the evenness of a lightness ramp, whether two grays are distinguishable — these are about the difference between two colors, and differences survive display variation far better than absolute values do. A pair that clears 4.5:1 in sRGB clears it on almost any reasonable display. This is why the checks in our accessible color guide are worth doing carefully.

Precision matters much less for absolutes. Agonising over whether the brand blue should be #3B82F6 or #3B83F7 is time spent on a distinction no user can perceive, on a screen you cannot control.

Build in tolerance. If a design only works when a border is exactly the right shade, it will fail somewhere. Give yourself margin: a slightly stronger border, a slightly higher contrast ratio than the minimum, a focus ring that is unmistakable rather than tasteful. Anything sitting right on a threshold will fall off it on somebody's monitor.

Practical steps

  1. Design in sRGB. It remains the safe common denominator for the web. Set your design tool's document profile explicitly rather than trusting the default.
  2. Export images as sRGB. Strip or convert wide-gamut profiles on anything that has to match a CSS value.
  3. Look at your work on a second device. A phone is the cheapest possible check, and it is where most people will see it anyway.
  4. Turn off night-shift when judging color. It is easy to spend an hour tuning a palette through an orange filter.
  5. Verify with numbers, not eyes, for anything that matters. Your monitor is an unreliable narrator; a contrast ratio is not. Run pairs through the contrast checker rather than judging by sight.

The newer CSS color functions

CSS has begun to address this directly. The color() function lets you specify which space you mean — color(display-p3 0.2 0.5 0.9) is explicit in a way a HEX code never is. Perceptual spaces like OKLCH, covered in our CSS color guide, go further by making equal numeric steps look like equal perceptual steps.

These do not eliminate display variation — nothing can, short of calibrating every user's monitor. What they do is remove the ambiguity about what you meant, which is a real improvement over hoping everyone assumes sRGB.

The short version

A HEX code is a request, and every screen answers it slightly differently. Chase precision in the relationships between your colors, where it holds up. Do not chase it in absolute values, where it does not survive contact with real hardware. And when a colleague says the blue looks different on their machine, they are almost certainly right — and it almost certainly does not matter.

If you want to see how a single color decomposes across every model at once, drop an image into the color detector and click a pixel, or read the color models guide for what each of those numbers is measuring.