colorsrgbweb designcss

Color spaces explained: sRGB, P3, gamma and why your colors shift

Why a color looks different on every screen: gamuts, sRGB and Display P3 spaces, gamma and transfer functions, and how to define colors correctly in CSS.

August 25, 2026·8 min read

That corporate red looking perfect on your MacBook and dull on the client's laptop isn't a bug or bad luck: it's the consequence of colors not traveling — descriptions travel, which every screen interprets with its own physics. Understanding gamuts, spaces and gamma turns frustration into control — and lets you use modern wide colors when they genuinely add value.

A digital color is a recipe, not a substance

rgb(220, 50, 30) doesn't define "red": it defines three relative intensities within a concrete system. The key question is always: intensities of which primaries, with which brightness curve, inside which possible triangle? That's a color space: primaries (reference pure colors), white point and transfer function (gamma).

The same numeric triple in two spaces produces physically different colors. Without declaring the space, the number means nothing universal.

Gamut: the triangle of the possible

A display can only emit colors within the triangle formed by its three subpixels:

  • sRGB (1996): the web's historical standard. Covers roughly 35% of visible colors. Everything else exists as specification but doesn't fit old screens.
  • Display P3 (~2015, Apple): same white point as sRGB but more saturated primaries, especially greens and reds. Covers ~45% visible. Today in iPhones, Macs, many Android OLEDs and mid-range monitors.
  • Rec.2020/ProPhoto: enormous gamuts used in professional video and mastering; consumer displays barely touch their interior.

When your design uses a color outside the device's gamut, clipping happens: it picks the nearest displayable neighbor. Hence the "washed out" look: that vivid P3 green gets clipped to sRGB's triangle edge.

Modern CSS: colors beyond sRGB

Historically CSS only spoke sRGB. Current syntax declares spaces explicitly:

.card {
  /* classic, still the base */
  background: rgb(89.57% 19.61% 11.76%);

  /* Display P3: more saturated where supported */
  @supports (color: color(display-p3 1 0 0)) {
    background: color(display-p3 0.898 0.292 0.089);
  }
}

And recent evolution goes further with perceptual spaces:

.oklch(55% 0.2 25)   /* lightness, chroma, hue */

OKLCH solves HSL's eternal problem: in HSL, two hues with the same "lightness" look differently bright because L isn't perceptually uniform. In OKLCH it is — that's why palettes generated with OKLCH keep real harmony across hues, something our palette generator leverages to build consistent combinations.

Gamma: the curve nobody sees

Camera sensors respond linearly to light; eyes don't — we're hypersensitive to shadow differences and insensitive at high lights. The transfer function (gamma) encodes exploiting that curve: more bits dedicated to shadows where we discriminate better.

Practical details flowing from here:

  • sRGB uses an approximate 2.2 curve; mislabeled content (an untagged image interpreted as linear) produces the classic washed-out or darkened result.
  • CSS gradients interpolate in the declared space; interpolating in sRGB generates the ugly grayish step between two saturated colors, while in oklch yields perceptually smooth transitions:
background: linear-gradient(in oklch, #ff0000, #0000ff);
  • hex ↔ rgb ↔ hsl conversions are pure math within one space; our color converter does them instantly, but remember no format conversion changes the gamut: that requires re-mapping color space.

Practical color management for web

Rules eliminating 90% of surprises:

  1. Work and deliver in sRGB unless there's a concrete reason. It's the common denominator and everything else falls back to it gracefully.
  2. Embedded ICC profile or nothing: a photo without a profile leaves the browser guessing (usually assuming sRGB, fine); a photo tagged with an odd profile landing on a non-managed destination, disaster.
  3. Calibrated screens for editing: without calibration you're applying makeup blindfolded. A basic hardware calibrator beats any expensive monitor without one.
  4. Use P3 as progressive enhancement only with @supports, never as exclusive base: on sRGB screens the browser clips and results vary by method.
  5. Always compare in the same environment: judging colors across two unprofiled monitors is judging two paintings under two different bulbs.

FAQ

Should I export my images in P3? Only if content loses something essential in sRGB (highly saturated product photography, vivid digital art) and you accept profile weight. For UI and general web, sRGB wins: full compatibility, smaller files.

Why does my screenshot look different pasted into another app? Untagged screenshots + apps without color management = free reinterpretation. Export with embedded profiles from serious apps.

Does OKLCH work everywhere already? All modern browsers support it (baseline 2023+). For wide production, define hex/rgb fallbacks before the modern declaration.


Convert between HEX, RGB, HSL and more with our color converter, free and right in your browser.

Try it without code

Color Converter

HEX, RGB, HSL and WCAG contrast.

Open Color Converter

Built by

Miguel Ángel Colorado Marin (MACM)

Full-Stack Developer · Guadalajara, España

I develop web apps, digital tools and full projects — from design to deployment.

Contact me