Why do we even need to know about color formats? Color is just... color, right? Not really. Different color formats behave differently on tweaking their values, affecting the color palette. By the end of this short blog you will understand why Tailwind moved to oklch
format in v4. Let's break down the formats.
Named Colors
If you are a frontend developer, you probably have used something like border: 1px solid red;
aka console.log()
of CSS.
Just like red
CSS has 140 named colors, like orange
, skyblue
, and even the legendary rebeccapurple
.
While these are super convenient for quick testing, but not ideal for production. Why? Because they don't make a good customizable color palette as there are limited options.
For example, here are some shades of orange:
papayawhip
peachpuff
salmon
tomato
orangered
RGB
This is one of the oldest color formats in CSS, based on how screens display color through combinations of red, green, and blue light.
In this format rgb(255,255,255)
each value represents intensity of color red, green, and blue, ranging from 0
to 255
.
By mixing different intensities we get almost every color on screen.
The rgba
format adds an alpha value for transparency, as shown below:
.old {
background-color: rgb(255, 51, 0, 0.5);
}
Now there is a new way to write this line in CSS Colors Module 4, it has some syntactic sugar for color functions:
.new {
background-color: rgb(255 51 0 / 0.5);
}
The slash acts as a delimiter which separates the alpha from the rgb values and is not part of the group, shows it is something different and not a math division.
R
G
B
A
Change the values above and you get total 16 million different colors.
Hex
Hex color format is just a fancy way to write the rgb values and widely used. For example, the base 16 hexadecimal #FF0000
for pure red can be split into three parts: FF
(red), 00
(green), 00
(blue).
Each part can have value from 00
to FF
making total combinations of 256 same as the range of rgb()
i.e 0
- 255
.
We can also use 3 digit shorthand in some hex value like #F00
for #FF0000
.
Now let's use a color palette from the colorhunt.co website:
#ECFAE5
#DDF6D2
#CAE8BD
#B0DB9C
Take a look, even for same shades of a color there is no consistency in the codes which makes it hard to guess a color from code and change it programmatically.
HSL
HSL is different from the previous color formats, a more human-friendly way to work with color in CSS.
-
H stands for Hue, which is what color pigment you want. The value is the angle of the color in the color wheel. Every degree has a different hue. It goes from
0
to360
.Some key hues:
-
0°
→ Red -
60°
→ Yellow -
120°
→ Green -
220°
→ Blue -
320°
→ Pink
There is a mnemonic to remember this: Roy G. Biv stands for Red, Orange, Yellow, Green, Blue, Indigo, Violet.
-
- S is for Saturation, the higher the saturation, the more colourful the color and the lower the saturation, the grayer it becomes.
100%
saturation = fully vivid color.0%
saturation = completely gray.

Saturation: 100%

Saturation: 0%
- L is for Lightness of that color, the more lightness it has, more white in it and less the lightness, more dark the color.
Here is the same color pallete in HSL format:
hsl(100, 70%, 95%)
hsl(100, 60%, 85%)
hsl(100, 40%, 70%)
hsl(100, 30%, 60%)
See the consistency in same shades.
OKLCH
OKLCH is a new way to use the CSS colors:
- OK : color space on human vision developed by Björn Ottosson (OKLab).
- L : For lightness, similar to HSL, with value
0
to1
. - C : Chroma similar to saturation with value greater than
0
It goes to infinity but we can see until a level only. - H : Hue from HSL with value of degree
0
to360
.
TL;DR — It's a more predictable and accessible way to define colors.
It is made on top of the lch color format with fixes of the lch format, build by the OKLab.
It was built to solve the problems of LCH(from CIELAB) and with some benefits:
-
It can generate the color palette from formula and no need to manually choose the colors.
-
It can display P3 color space.
-
Has better a11y(accessibility) and has predictable lightness.
-
Human readable tweaks in values of
l
,c
andh
.
But why switch to OKLCH?
The problem with HSL is that the color space of HSL is not consistent. Identical saturation and lightness values creates different contrasts in the colors.
hsl(270 100% 50%)
hsl(90 100% 50%)
oklch(0.5 0.29 294)
oklch(0.5 0.29 135)
Even for same saturation and lightness in HSL the contrast changes but in for OKLCH it is same. This happens because the lightness in HSL is not accurate.
OKLCH's predictable lightness makes it easier to create accessible color palettes. For example, ensuring a contrast ratio of 4.5:1 for text (per WCAG 2.1) is simpler with OKLCH because adjusting L (lightness) doesn't unexpectedly alter hue or saturation, unlike HSL.
This concept is explained in detailed in this Evil Martians blog
P3 Colors
As we know that our eyes have a visible color range, that range is currently not fully shown by our displays. Earlier with the LCD displays we could only see the Standard RGB colors(sRGB) but with time and development in technology we have extended the range of the displays even further. There are many range like Adobe RGB, REC.2020, etc. But in CSS we have DCI-P3 or P3 which you can see in the below image:
The P3 color space (DCI-P3) is a wider range of colors than sRGB, used in modern displays like OLED screens. While RGB, Hex, and HSL are limited to sRGB (within the white line in the above image), OKLCH can define P3 colors and even colors beyond P3. If a device can't display a P3 color, OKLCH applies gamut correction, automatically adjusting to the closest displayable shade for consistent results across devices.
Try out this OKLCH Color picker.
Color modifications
The l
, c
and h
values of OKLCH can be reused and changed with the calc()
function of css, For example let's take a variable color named --destructive
and decrease the lightness by 0.1.
As I have different values for light mode and dark mode try switching modes and observe that it works consistently for both.
How OKLCH Handles Light Better
As mentioned earlier the HSL's lightness problem with change in lightness the saturation and hue gets affected, so now let's compare with different colors and see how both HSL and OKLCH handles light.
Color Lightness Comparison
HSL
OKLCH
Notice how the increments in the OKLCH are more natural. That's why Tailwind switched to OKLCH in v4.
The more you learn about colors the more you will know that you little you knew about it.
Liked my work? Let's connect
Build a website with me