Colors Used in Computers

If you asked me a few months ago, “What does it take for a website to stand out?” I may have said fancy animations, creative layouts, cool interactions, and maybe just the general aesthetics, without pointing out something in particular. If you ask me now, after working on color for the better part of the year, I can confidently say it’s all color. Among all the aspects that make a design, a good color system will make it as beautiful as possible.

However, color in CSS can be a bit hard to fully understand since there are many ways to set the same color, and sometimes they even look the same, but underneath are completely different technologies. That’s why, in this guide, we will walk through all the ways you can set up colors in CSS and all the color-related properties out there!

Colors are in everything

They are in your phone, in what your eye sees, and on any screen you look at; they essentially capture everything. Design-wise, I see the amazing use of colors on sites listed over at awwwards.com, and I’m always in awe.

Not all color is the same. In fact, similar colors can live in different worlds, known as color spaces. Take for example, sRGB, the color space used on the web for the better part of its existence and hence the most known. While it’s the most used, there are many colors that are simply missing in sRGB that new color spaces like CIELAB and Oklab bring, and they cover a wider range of colors sRGB could only dream of.

What’s a color space?

A color space is the way we arrange and represent colors that exist within a device, like printers and monitors. We have different types of color spaces that exist in media (Rec2020, Adobe RGB, etc), but not all of them are covered in CSS. Luckily, the ones we have are sufficient to produce all the awesome and beautiful colors we need. In this guide, we will be diving into the three main color spaces available in CSS: sRGB, CIELAB, and OkLab.

The sRGB Color Space

The sRGB is one of the first color spaces we learn. Inside, there are three color functions, which are essentially notations to define a color: rgb()hsl(), and hwb().

sRGB has been a standard color space for the web since-1996. However, it’s closer to how old computers represented color, rather than how humans understand it, so it had some problems like not being able to capture the full gamut of modern screens. Still, many modern applications and websites use sRGB, so even though it is the “old way” of doing things, it is still widely accepted and used today.

  • 3-digit hexadecimal. The 3-digit hexadecimal system is a shorter way of writing the 6-digit hexadecimal system, where each value represents the color’s redness, greenness, and blueness, respectively
.element {
  color: #abc;
}

In reality, each value in the 3-digit system is duplicated and then translated to a visible color

.element {
  color: #abc; /* Equals #AABBCC  */
}

BUT, this severely limits the colors you can set. What if I want to target the color 213 in the red space, or how would I get a blue of value 103? It’s impossible. That’s why you can only get a total number of 4,096 colors here as opposed to the 17 million in the 6-digit notation. Still, if you want a fast way of getting a certain color in hexadecimal without having to worry about the millions of other colors, use the 3-digit notation.

  • 4-digit hexadecimal. This is similar to the 3-digit hexadecimal notation except it includes the optional alpha value for opacity. It’s a shorter way of writing the 8-digit hexadecimal which also means that all values here are repeated once during color translation.
.element {
  color: #abcd; /* Same as #AABBCCDD */
}

For the alpha value, 0 represents 00 (a fully transparent color) and F represents FF (a fully opaque color).

  • 6-digit hexadecimal. The 6-digit hexadecimal system just specifies a hexadecimal color’s redness, blueness, and greenness without its alpha value for color opacity.
.element {
  color: #abcdef;
}
  • 8-digit hexadecimal. This 8-digit hexadecimal system specifies hexadecimal color’s redness, blueness, greenness, and its alpha value for color opacity. Basically, it is complete for color control in sRGB.
.element {
  color: #faded101;
}

Both hsl() and rgb() live in the sRGB space, but they access colors differently. And while the consensus is that hsl() is far more intuitive than rgb(), it all boils down to your preference.

hsl() takes three values: hs, and l, which set its hue, saturation, and lightness, respectively.

  • The hue sets the base color and represents a direction in the color wheel, so it’s written in angles from 0deg to 360deg.
  • The saturation sets how much of the base color is present and goes from 0 (or 0%) to 100 (or 100%).
  • The lightness represents how close to white or black the color gets.

One cool thing: the hue angle goes from (0deg360deg), but we might as well use negative angles or angles above 360deg, and they will circle back to the right hue. Especially useful for infinite color animation. Pretty neat, right?

Plus, you can easily get a complementary color from the opposite angle (i.e., adding 180deg to the current hue) on the color wheel.

/* Current color */
.element {
  color: hsl(120deg 40 60 / 0.8);
}

/* Complementary color */
.element {
  color: hsl(300deg 40 60 / 0.8);
}

You want to combine the two syntax formats like in rgb(), yes? That’s also a no-no. It won’t work.

/* This would not work */
.element {
  color: hsl(130deg, 50, 20 / 0.5);
}

/* Neither will this */
.element {
  color: hsl(130deg 50 20, 0.5);
}

/* Or this */
.element {
  color: hsl(130deg 50, 20 / 0.5);
}

Instead, stick to one of the syntaxes, like in rgb():

/* Valid (Modern syntax)  */ 
.element {
  color: hsl(130deg 50 20 / 0.5);
}

/* Valid (Modern syntax)  */ 
.element {
  color: hsl(130deg, 50, 20, 0.5);
}

hwb() also uses hue for its first value, but instead takes two values for whiteness and blackness to determine how your colors will come out (and yes, it also does have an optional transparency value, a, just like rgb() and hsl()).

.element {
  color: hwb(80deg 20 50 / 0.5);
}
  • The first value h is the same as the hue angle in hsl(), which represents the color position in the color wheel from 0 (or 0deg) to 360 (or 360deg).
  • The second value, w, represents the whiteness in the color. It ranges from 0/0% (no white) to 100/100% (full white if b is 0).
  • The third value, b, represents the blackness in the color. It ranges from 0/0% (no black) to 100/100% (fully black if w is 0).
  • The final (optional) value is the alpha value, a, for the color’s opacity, preceded by a forward slash The value’s range is from 0.0 (or 0%) to 1.0 (or 100%).

Although this color function is barely-used, it’s completely valid to use, so it’s up to personal preference.

The CIELAB Color Space

The CIELAB color space is a relatively new color space on the web that represents a wider color gamut, closer to what the human eye can see, so it holds a lot more color than the sRGB space.

For this color function, we have three axes in a space-separated list to determine how the color is set.

.element {
    color: lab(50 20 20 / 0.9);
}
  • The first value l represents the degree of whiteness to blackness of the color. Its range being 0/(or 0%) (black) to 100 (or 100%) (white).
  • The second value a represents the degree of greenness to redness of the color. Its range being from -125/0% (green) to125 (or 100%) (red).
  • The third value b represents the degree of blueness to yellowness of the color. Its range is also from -125 (or 0%) (blue) to 125 (or 100%) (red).
  • The fourth and final value is its alpha value for color’s opacity. The value’s range is from 0.0 (or 0%) to 1.0 (or 100%).

This is useful when you’re trying to obtain new colors and provide support for screens that do support them. Actually, most screens and all major browsers now support lab(), so you should be good.

The CSS lab() color function’s a and b values are actually unbounded. Meaning they don’t technically have an upper or lower limit. But, at practice, those are their limits according to the specifications.

The CSS lch() color function is said to be better and more intuitive than lab().

.element {
    color: lch(10 30 300deg);
}

They both use the same color space, but instead of having la, and blch uses lightness, chroma, and hue.

  • The first value l represents the degree of whiteness to blackness of the color. Its range being 0 (or 0%) (black) to 100 (or 100%) (white).
  • The second value c represents the color’s chroma (which is like saturation). Its range being from 0 (or 100%) to 150 or (or 100%).
  • The third value h represents the color hue. The value’s range is also from 0 (or 0deg) to 360 (or 360deg).
  • The fourth and final value is its alpha value for color’s opacity. The value’s range is from 0.0 (or 0%) to 1.0 (or 100%).

The CSS lch() color function’s chroma (c) value is actually unbounded. Meaning it doesn’t technically have an upper or lower limit. But, in practice, the chroma values above are the limits according to the specifications.

The OkLAB Color Space

Björn Ottosson created this color space as an “OK” and even better version of the lab color space. It was created to solve the limitations of CIELAB and CIELAB color space like image processing in lab(), such as making an image grayscale, and perceptual uniformity. The two color functions in CSS that correspond to this color space are oklab() and oklch().

Perceptual uniformity occurs when there’s a smooth change in the direction of a gradient color from one point to another. If you notice stark contrasts like the example below for rgb() when transitioning from one hue to another, that is referred to as a non-uniform perceptual colormap.

Notice how the change from one color to another is the same in oklab() without any stark contrasts as opposed to rgb()? Yeah, OKLab color space solves the stark contrasts present and gives you access to many more colors not present in sRGB.

OKlab actually provides a better saturation of colors while still maintaining the hue and lightness present in colors in CIELAB (and even a smoother transition between colors!).

The oklab() color function, just like lab(), generates colors according to their lightness, red/green axis, blue/yellow axis, and an alpha value for color opacity. Also, the values for oklab() are different from that of lab() so please watch out for that.

.element {
  color: oklab(30% 20% 10% / 0.9);
}
  • The first value l represents the degree of whiteness to blackness of the color. Its range being 0 (or 0%) (black) to 0.1 (or 100%) (white).
  • The second value a represents the degree of greenness to redness of the color. Its range being from -0.4 (or -100%) (green) to 0.4 (or 100%) (red).
  • The third value b represents the degree of blueness to yellowness of the color. The value’s range is also from -0.4 (or 0%) (blue) to 0.4 (or -100%) (red).
  • The fourth and final value is its alpha value for color’s opacity. The value’s range is from 0.0 (or 0%) to 1.0 (or 100%).

Again, this solves one of the issues in lab which is perceptual uniformity so if you’re looking to use a better alternative to lab, use oklab().

The CSS oklab() color function’s a and b values are actually unbounded. Meaning they don’t technically have an upper or lower limit. But, theoretically, those are the limits for the values according to the specifications.

The oklch() color function, just like lch(), generates colors according to their lightness, chroma, hue, and an alpha value for color opacity. The main difference here is that it solves the issues present in lab() and lch().

.element {
  color: oklch(40% 20% 100deg / 0.7);
}
  • The first value l represents the degree of whiteness to blackness of the color. Its range being 0.0 (or 0%) (black) to 1.0 (or 100%) (white).
  • The second value c represents the color’s chroma. Its range being from 0 (or 0%) to 0.4 (or 100%) (it theoretically doesn’t exceed 0.5).
  • The third value h represents the color hue. The value’s range is also from 0 (or 0deg) to 360 (or 360deg).
  • The fourth and final value is its alpha value for color’s opacity. The value’s range is from 0.0 (or 0%) to 1.0 (or 100%).

The CSS oklch() color function’s chroma (c) value is actually unbounded. Meaning it doesn’t technically have an upper or lower limit. But, theoretically, the chroma values above are the limits according to the specifications.

The color(colorspace c1 c2 c2/α) function allows access to colors in nine different color spaces, as opposed to the previous color functions mentioned, which only allow access to one.

To use this function, you must simply be aware of these 6 parameters:

  • The first value specifies the color space you want to access colors from. They can either be srgbsrgb-lineardisplay-p3a98-rgbprophoto-rgbrec2020xyzxyz-d50, or xyz-d65
  • The next three values (c1c2, and c3) specifies the coordinates in the color space for the color ranging from 0.0 – 1.0.
  • The sixth and final value is its alpha value for color’s opacity. The value’s range is from 0.0 (or 0%) to 1.0 (or 100%).

The color-mix(in colorspace, c1 p1, c2 p2) function mixes two colors of any type in a given color space. Basically, you can create an endless number of colors with this method and explore more options than you normally would with any other color function. A pretty powerful CSS function, I would say.

.element {
  color-mix(in oklab, hsl(40 20 60) 80%, red 20%);
}

You’re basically mixing two colors of any type in a color space. Do take note, the accepted color spaces here are different from the color spaces accepted in the color() function.

To use this function, you must be aware of these three values:

  • The first value in colorspace specifies the interpolation method used to mix the colors, and these can be any of these 15 color spaces: srgbsrgb-lineardisplay-p3a98-rgbprophoto-rgbrec2020laboklabxyzxyz-d50xyz-d65hslhwblch, and oklch.
  • The second and third values specifies an accepted color value and a percentage from 0% to 100%.

Properties that support color values

There are a lot of properties that support the use of color. Just so you know, this list does not contain deprecated properties.

  1. accent-color --> Accent colors are a way to style unique elements in respect to the chosen color scheme;
  2. background-color --> Applies solid colors as background on an element.
  3. border-color --> Shorthand for setting the color of all four borders;
  4. box-shadow  --> Adds shadows to element for creating the illusion of depth. The property accepts a number of arguments, one of which sets the shadow color;
  5. caret-color --> Specifies the color of the text input cursor (caret);
  6. color --> Sets the foreground color of text and text decorations;
  7. column-rule-color --> Sets the color of a line between columns in a multi-column layout. This property can’t act alone, so you need to set the columns and column-rule-style property first before using this;
  8. fill --> Sets the color of the SVG shape;
  9. flood-color --> Specifies the flood color to use for <feFlood> and <feDropShadow> elements inside the <filter> element for <svg>. This should not be confused with the flood-color CSS attribute, as this is a CSS property and that’s an HTML attribute (even though they basically do the same thing). If this property is specified, it overrides the CSS flood-color attribute;
  10. lighting-color --> Specifies the color of the lighting source to use for <feDiffuseLighting> and <feSpecularLighting> elements inside the <filter> element for <svg>;
  11. outline-color --> Sets the color of an element’s outline;
  12. stop-color --> Specifies the color of gradient stops for the <stop> tags for <svg>;
  13. stroke --> Defines the color of the outline of <svg>;
  14. text-decoration-color --> Sets the color of text decoration lines like underlines;
  15. text-emphasis-color --> Specifies the color of emphasis marks on text;
  16. text-shadow --> Applies shadow effects to text, including color.
Code

Here, we get into the details of how thses colors systems renders colous which are functions in-built inside the CSS3-Specifications and I'm going to discuss all in details as under:

  • The rgb() Function: Let's dive in to this function and finds everything about this function, the arguments used inside this functions and other useful details; rgb(r, g, b / a) where, r --> Red, g --> Green, b --> Blue and α --> Alpha; The Range of r is in-between 0-255, g is also in-between 0-255 and b is also in-between 0-255, moreover the range of a (alpha) is in-between 0-1. First three arguments used to provide the three primary colors RED, GREEN and BLUE whose composition is decided by the ranges as dicussed earlier and the last argument is for opacity where 0 (or 0%) for complete-transparent and 1(or 100%) for complete-opaque.

Ex- .element { color: rgb(245 123 151); }; .element { color: rgb(245 123 151 / 20%); }

  • The rgba() Function: Let's dive in to this function and finds everything about this function, the arguments used inside this functions and other useful details; rgb(r, g, b / α) where, r --> Red, g --> Green, b --> Blue and α --> Alpha; The Range of r is in-between 0-255, g is also in-between 0-255 and b is also in-between 0-255, moreover the range of a (alpha) is in-between 0-1. First three arguments used to provide the three primary colors RED, GREEN and BLUE whose composition is decided by the ranges as dicussed earlier and the last argument is for opacity where 0 (or 0%) for complete-transparent and 1(or 100%) for complete-opaque. Both are same in todays scenario.

Ex- .element { color: rgb(245 123 151); }; .element { color: rgb(245 123 151 / 20%); }

  • The hexadecimal notation: The hexadecimal CSS color code is a 3, 4, 6, or 8 (being the maximum) digit code for colors in sRGB. It’s basically a shorter way of writing rgb(). The hexadecimal color (or hex color) begins with a hash token (#) and then a hexadecimal number, which means it goes from 0 to 9 and then skips to letters a to f (a being 10, b being 11, and so on, up to f for 15). In the hexadecimal color system, the 6-digit style is done in pairs. Each pair represents red (RR), blue (BB), and green (GG). Each value in the pair can go from 00 to FF, which it’s equivalent to 255 in rgb().Notice how I used caps for the letters (F) and not lowercase letters like I did previously? Well, that’s because hexadecimals are not case-sensitive in CSS, so you don’t have to worry about uppercase or lowercase letters when dealing with hexadecimal colors.
  • The hsl() function: The hsl(h s l/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: h --> Hue (range is in-between 0 degree to 360 degrees), s --> Saturation (range is in-between 0(0%) to 100(100%)), and l --> Lightness (range is in-between 0 to 100), moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The hsla() function: The hsla(h s l/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: h --> Hue (range is in-between 0 degree to 360 degrees), s --> Saturation (range is in-between 0(0%) to 100(100%)), and l --> Lightness (range is in-between 0 to 100), moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The hwb() function: The hwb(h w b/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: h --> Hue (range is in-between 0 degree to 360 degrees), w --> Whiteness (range is in-between 0 to 100), and b --> Blackness(range is in-between 0 to 100), moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The lab() function: The lab(l a b/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: l --> degree of whiteness to darkness (range is in-between 0(0%) to 100(100%)), a --> degree of greenness to redness(range is in-between -125(0% - 'green') to 125(100% - 'red')) of color, and b --> to degree of blueness to yellowness(range is in-between -125(0% - 'blue') to 125(100% - 'yellow')) of color, moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The lch() function: The lch(l c h/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: l --> degree of whiteness to blackness (range is in-between 0(0%) to 100(100%)), c --> color (range is in-between 0(0%) to 150(100%)) chroma, and h --> Hue (range is in-between 0 degree to 360 degrees), moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The oklab() function: The oklab(l a b/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: l --> degree of whiteness to darkness (range is in-between 0(0%) to 100(100%)), a --> degree of greenness to redness(range is in-between -0.4(0% - 'green') to 0.4(100% - 'red')) of color, and b --> to degree of blueness to yellowness(range is in-between -0.4(0% - 'blue') to 0.4(100% - 'yellow')) of color, moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The oklch() function: The oklch(l c h/α) is also very useful function used in the WEB-DESIGNING field having FOUR-ARGUMENTS with the ranges as under: l --> degree of whiteness to blackness (range is in-between 0(0%) to 1(100%)), c --> color (range is in-between 0(0%) to 0.4(100%)) chroma, and h --> Hue (range is in-between 0 degree to 360 degrees), moreover the range of α(alpha) is in-between 0-1 which caters the tranparence <---> Opaquecity of colors.
  • The color() function: The color(colorspace c1 c2 c3/α) is also very useful function used in the WEB-DESIGNING field having FIVE-ARGUMENTS with the ranges as under: colorspace --> NINE-ACCEPTED-COLOR-SPACES you can used her from amongst (srgb, srgb-linear, display-p3, α98-rgb, prophoto-rgb, rec2020, xyz, xyz-d50 or xyz-d65) colorspaces; c1 --> first color-space (range is in-between 0.0(0%) to 1.0(100%)) coordinate, c2 --> second color-space (range is in-between 0.0(0%) to 1.0(100%)) coordinate, c3 --> thirdcolor-space (range is in-between 0.0(0%) to 1.0(100%)) coordinate and moreover, the sixth argument α(alpha) is in-between 0.0(0%)-1.0(100%) which caters the tranparence <---> Opaquecity of colors.
  • The color-mix() function: The color-mix(in colorspace, c1 p1, c2 p2) is also very useful function used in the WEB-DESIGNING field having THREE-ARGUMENTS with the ranges as under: in --> mandatory-keyword specifies the interpolation method, colorspace --> FIFTEEN-ACCEPTED-COLOR-SPACES you can used her from amongst (srgb, srgb-linear, display-p3, α98-rgb, prophoto-rgb, rec2020, xyz, xyz-d50, xyz-d65, lab, oklab, hsl, hwb, lch or oklch) colorspaces and moreover argument(s) c1 p1 and c2 p2 can be used here as c1 - c2 --> denotes any valid color input and p1 - p2 --> denotes color amount (0% - 100%).
  • The color-function() function: The color-function(from origin-color c1 c2 c3/α) is also very useful function used in the WEB-DESIGNING field having SIX-ARGUMENTS with the ranges as under: from --> mandatory-keyword specifies you must set to extract the color values from origin-color, origin-color--> represents a color function or value or even another relative color that you want to get color from, c1, c2 & c2represent the current color function’s color channels and they correspond with the color function’s valid color values and moreover the sixth argument α(alpha) is in-between 0.0(0%)-1.0(100%) which caters the tranparence <---> Opaquecity of colors.
  • .progress { accent-color: lightgreen; }.
  • .element { background-color: #ff7a18; }
  • /* Sets all border colors */ .element { border-color: lch(50 50 20); } /* Sets top, right, bottom, left border colors */ .element { border-color: black green red blue; }
  • .element { box-shadow: 0 3px 10px rgb(0 0 0 / 0.2); }
  • .element { caret-color: lch(30 40 40); }
  • .element { color: lch(80 10 20); }
  • .element { column: 3; column-rule-style: solid; column-rule-color: lch(20 40 40); /* highlight */ }
  • .element { fill: lch(40 20 10); }
  • .element { flood-color: lch(20 40 40); }
  • .element { lighting-color: lch(40 10 20); }
  • .element { outline-color: lch(20 40 40); }
  • .element { stop-color: lch(20 40 40); }
  • .element { stroke: lch(20 40 40); }
  • .element { text-decoration-color: lch(20 40 40); }
  • .element { text-emphasis-color: lch(70 20 40); }
  • .element { text-shadow: 1px 1px 1px lch(50 10 30); }

 

 

Select Chapter