Numbers need a space
An RGB value is three numbers, and the numbers only become a color once you know which red, green and blue they are mixing. MDN's definition of a color space is a named organization of colors with a mathematical model and a defined gamut, the range of colors it can represent. sRGB fixes one particular set of primaries; Display P3 fixes a more saturated set. The value 1 0 0 is "all of the red primary" in both, but P3's red primary is further out, so the same three numbers are a more vivid color.
The web's default is sRGB. The CSS Color specification requires that colors in HTML and untagged images be treated as sRGB, and MDN notes that sRGB was created for the web and is the assumed space for anything without an embedded profile. Every hex code, rgb() and hsl() value, and the color converter's outputs, live there.
The predefined spaces and how big they are
CSS Color Level 4 defines a set of named spaces and compares their gamuts in a common unit:
| Space | CSS name | Gamut volume (million Lab units) | Relative to sRGB | What it is |
|---|---|---|---|---|
| sRGB | srgb | 0.820 | 1.00× | The standard web and PC space; what untagged images and CSS colors are assumed to be in |
| Display P3 | display-p3 | 1.233 | 1.50× | DCI-P3 cinema primaries with a D65 white point and the sRGB transfer curve; typical of current wide-gamut screens |
| A98 RGB | a98-rgb | 1.310 | 1.60× | The Adobe RGB-compatible space used in photo workflows |
| Rec. 2020 | rec2020 | 2.042 | 2.49× | ITU-R BT.2020 for ultra-high-definition television |
| ProPhoto RGB | prophoto-rgb | 2.896 | 3.53× | A very wide archival space for photography, with a D50 white point |
Display P3, in the specification's words, uses the same primary chromaticities as DCI-P3 but with a D65 white point and the same transfer curve as sRGB, which is why its numbers behave like sRGB's and only the corners move. MDN describes it as typical of current wide-gamut monitors and says it enables more vibrant greens and reds than sRGB. Rec. 2020 and ProPhoto are wider still; MDN notes that Rec. 2020 reaches almost all visible colors, beyond most current displays.
What a screen does with colors it cannot show
A P3 color on an sRGB display cannot be reproduced, and the specification says what happens instead: the color is gamut mapped, producing a similar-looking but lower-chroma, less saturated color. The hue and lightness survive, the vividness does not. The reverse is harmless: every sRGB color is inside P3, so sRGB content looks the same on a wide-gamut screen, just with headroom unused. That asymmetry is the whole design rule: design in sRGB and add P3 where it helps, never the other way round.
Using P3 in CSS
MDN describes the color() function as a way to specify a color in a particular color space rather than the implicit sRGB of the other color functions. Declare the sRGB value first so browsers and displays without wide-gamut support keep a sensible color:
.brand {
background: rgb(255 0 0); /* sRGB fallback */
background: color(display-p3 1 0 0); /* wider red where supported */
}
@media (color-gamut: p3) {
.hero { background: color(display-p3 0.1 0.8 0.3); }
} The color-gamut media feature reports what the screen can do: MDN gives srgb for the vast majority of color displays, p3 for devices that support approximately the Display P3 gamut or more, which is larger than and includes sRGB, and rec2020 for the widest. Gradients between saturated colors are a natural use of the extra room; the CSS gradient generator produces the sRGB version to start from. Whatever the space, the contrast rules do not change, and the color contrast checker still decides whether text is readable.
Images and profiles
- Untagged means sRGB. An image exported in P3 without an embedded profile is read as sRGB and its colors shift. If you export wide gamut, keep the profile in the file.
- Picking colors from photos. The color picker from image returns sRGB hex codes, which is the right value for a hex-based stylesheet; a P3 photo's extra saturation is not expressible in hex.
- Compression can strip profiles. Check that a P3-tagged image still carries its profile after it has been through an optimizer; if the tool drops it, export sRGB instead.
- Print is another space entirely. CMYK gamuts are smaller and shaped differently; neither sRGB nor P3 predicts what a press prints, which is what the PPI vs DPI guide touches on from the resolution side.
Frequently asked questions
What is a color space?
MDN defines color spaces as named organizations of colors built on a color model, each with a mathematical definition and a defined gamut, the range of colors it can represent. sRGB and Display P3 use the same red, green and blue model; they differ in which actual red, green and blue sit at the corners, so the same numbers mean different colors in each.
Is Display P3 better than sRGB?
It is larger. MDN describes Display P3 as a wide gamut space typical of current wide-gamut monitors that enables more vibrant greens and reds than sRGB, and the CSS color specification's own comparison gives it about 1.5 times the volume. Better depends on the screen: on an sRGB display the extra colors cannot be shown and are mapped to the nearest in-gamut color.
What happens to a P3 color on an ordinary screen?
It is gamut mapped. The CSS Color specification says a color outside the display's gamut is mapped to a similar-looking but lower-chroma, less saturated color. So a vivid P3 red becomes the most saturated red sRGB can show; nothing breaks, the color is just duller than intended.
How do I use P3 in CSS?
With the color() function and a predefined space, for example color(display-p3 1 0 0), which MDN describes as a way to specify a color in a particular color space instead of the implicit sRGB that rgb() and hex use. Give an sRGB value first as a fallback, and the color-gamut media query lets you serve P3 colors only to screens that can show them.
Should I export images in P3?
Only when the colors need it and the file carries a profile. The CSS Color specification says untagged images must be treated as sRGB, so a P3 export without an embedded profile will be read as sRGB and look wrong. For most web images, sRGB remains the safe default; P3 is for product shots and artwork where the saturated colors matter and the file is tagged.
Sources
- W3C CSS Color Module Level 4 (the predefined color spaces srgb, display-p3, a98-rgb, prophoto-rgb and rec2020 with their definitions; the gamut comparison table in millions of Lab units; untagged images and HTML colors treated as sRGB; gamut mapping to a lower-chroma color)
- MDN Web Docs: Color space (definition; sRGB created for the web and assumed for untagged content; Display P3 as a wide gamut space with more vibrant greens and reds; Rec. 2020 beyond most displays)
- MDN Web Docs: color() and the color-gamut media feature (specifying a color in a named space; the srgb, p3 and rec2020 values of the media query)