Future of colors on the Web

by Alexey Ivanov

Clients

Open Source

Let's talk about colors

Color spaces

Colors that people can see

https://commons.wikimedia.org/wiki/

File:CIExy1931.svg

Color spaces

sRGB

https://en.wikipedia.org/wiki/

File:SRGB_chromaticity_CIE1931.svg

Color spaces

display-p3

https://en.wikipedia.org/wiki/

File:CIE1931xy_gamut_comparison_

of_sRGB_P3_Rec2020.svg

Device support

  • Apple devices released after 2016.
  • Modern Android phones.
  • Professional displays.

Cool, so how can we use them?

CSS Color Module Level 3

red

#ff0000

rgb(255, 0, 0)

rgba(255,0,0, 100%)

hsl(0, 100%, 50%)

hsla(0, 100%, 50%, 100%)

rgb(255, 0, 0)

red 0-255

green 0-255

blue 0-255

https://en.wikipedia.org/wiki/

File:CIE1931xy_gamut_comparison_

of_sRGB_P3_Rec2020.svg

CSS Color Module Level 4

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

Browser support

So, which one to choose?

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

Color quiz

rgb(120 90 85)

rgb(120 90 85)

rgb(75 130 240)

rgb(75 130 240)

rgb(155 104 103)

rgb(160 25 250)

rgb(155 104 103)

rgb(160 25 250)

If we can read colors, we can do cool things

What colors are readable

  • Human-readable axis (lightness instead of the amount of red).
  • All axes should be independent. Changing the value of a hue’s axis color should maintain the same level of contrast. Saturation changes should not change hue.

Example of unpredictable color changes

hsl(0 100% 50%)

hue - 0-360

saturation - 0%-100%

lightness - 0%-100%

https://en.wikipedia.org/wiki/

File:SRGB_chromaticity_CIE1931.svg

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

lch() and lab() VS oklch() and oklab()

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

oklab()

lightness – 0%-100%

a – 0-1, cartesian coordinates between green and red.

b – 0-1, cartesian coordinates between blue and yellow.

oklch()

lightness – 0%-100%

chroma – 0 to infinity.

hue – 0-360.

Old and improved:

#FF000000

rgb(0 255 0 / 1)

hsl(0 100% 50% / 1)

New:

hwb(0 0% 0%)

color(sRGB 0 1 0)

color(display-p3 0.92 0.2 0.14)

lab(54.29 80.8 69.89)

lch(54.29 106.84 40.86)

oklab(62.8% 0.22 0.13)

oklch(62.8% 0.26 30)

TLDR

  1. New displays support more colors than the old ones.
  2. To declare new colors, we need new formats.
  3. The oklch() is one of these formats and is the easiest for people to read and modify.

OKLCH for designers

Complimentary colors

A
B
C
D
E
F

oklch(75% 0.1 60)

oklch(75% 0.1 120)

oklch(75% 0.1 180)

oklch(75% 0.1 240)

oklch(75% 0.1 300)

oklch(75% 0.1 380)

Buttons

Button A
Button B

Normal:

Hovered:

Disabled:

oklch(50% 0.3 135)
oklch(60% 0.3 135)
oklch(80% 0.1 135)

Normal:

Hovered:

Disabled:

oklch(50% 0.3 30)
oklch(60% 0.3 30)
oklch(80% 0.1 30)

Flat colors

Contrast colors

Flat colors

Contrast colors

Risk color scheme

Risk color scheme

DEMO

OKLCH for fronteders

Checking the support

.martian {
  background: oklch(69.73% 0.155 112.79);
}
@media (color-gamut: p3) {
  .martian {
    background: oklch(69.73% 0.176 112.79);
    /* You'll only see the preview with P3 monitors */
  }
}

Gradients

.oklch {
    background: linear-gradient(in oklab, blue, green);
}

Gradients

Polyfils

  • @csstools/postcss-oklab-function
  • postcss-preset-env
  • Lightning CSS

Bonus

CSS Color Module Level 5

Color modifications with CSS

.button {
  background: var(--button-color);
}
.button:hover {
  /* One :hover for normal, secondary, and error states */
  background: oklch(from var(--button-color) calc(l + 10%) c h);
}

.button {
  --button-color:   var(--accent);
}
.button.is-secondary {
  --button-color:   var(--dimmed);
}
.button.is-error {
  --button-color:   var(--error);
}

Thanks!