In CSS and web design, the same colour can be expressed in multiple formats: #FF6347, rgb(255, 99, 71), and hsl(9, 100%, 64%) all represent exactly the same tomato-red colour. Choosing the right format is about readability, adjustability, and fit for your workflow — not about which produces a different colour.
Hex Colours
Hex (hexadecimal) colours are the most widely used format in web development. A hex colour is a 6-character code preceded by #, encoding the red, green, and blue channels as base-16 pairs:
#FF6347 /* R=FF=255, G=63=99, B=47=71 */ #000000 /* Black */ #FFFFFF /* White */ #336699 /* A muted blue */
Shorthand: When both characters in a pair are the same, you can use 3-character shorthand: #F63 = #FF6633.
8-digit hex with alpha: #FF634780 — the last two digits represent opacity (00=transparent, FF=opaque).
Use hex when: copying colours from design tools (Figma, Photoshop export hex by default), working with brand colours, or referencing colours from a style guide.
RGB Colours
RGB defines colour using three channel values, each from 0 to 255:
rgb(255, 99, 71) /* Tomato red */ rgb(0, 0, 0) /* Black */ rgb(255, 255, 255) /* White */ rgba(255, 99, 71, 0.5) /* 50% transparent tomato red */
The rgba() function adds an alpha channel (0 = fully transparent, 1 = fully opaque), making RGB the traditional go-to format when transparency is needed.
Use RGB when: you need transparency (rgba), when you are processing colour values mathematically in JavaScript, or when working with canvas or WebGL.
HSL Colours
HSL defines colour by three human-readable properties:
- Hue (H): A degree on the colour wheel (0°/360° = red, 120° = green, 240° = blue).
- Saturation (S): How vivid/grey the colour is (0% = greyscale, 100% = full vivid colour).
- Lightness (L): How light or dark (0% = black, 50% = normal, 100% = white).
hsl(9, 100%, 64%) /* Tomato red */ hsl(9, 100%, 50%) /* Darker tomato — just change L */ hsl(9, 100%, 80%) /* Lighter tomato — just change L */ hsl(120, 100%, 64%) /* Same saturation/lightness, green hue */ hsla(9, 100%, 64%, 0.5) /* 50% transparent */
HSL is much more intuitive to adjust manually than hex or RGB. To create a lighter shade of a brand colour, just increase Lightness. To create a muted version, reduce Saturation. To generate a complementary colour, add 180° to the Hue. This makes HSL ideal for design systems and CSS custom properties.
Comparison Table
| Format | Example | Transparency | Best for |
|---|---|---|---|
| Hex | #FF6347 | #RRGGBBAA | Design tool output, brand colours |
| RGB | rgb(255,99,71) | rgba() | JavaScript, canvas, maths |
| HSL | hsl(9,100%,64%) | hsla() | CSS variables, design systems, themes |
CSS Custom Properties and HSL — A Powerful Combination
A common modern pattern uses HSL with CSS custom properties to build a themeable colour system:
:root {
--color-primary-h: 220;
--color-primary-s: 90%;
--color-primary-l: 56%;
--color-primary: hsl(var(--color-primary-h), var(--color-primary-s), var(--color-primary-l));
--color-primary-light: hsl(var(--color-primary-h), var(--color-primary-s), 75%);
--color-primary-dark: hsl(var(--color-primary-h), var(--color-primary-s), 35%);
}
This makes it trivial to generate light and dark variants of any colour, or to switch themes by changing just the H, S, L variables.
Modern Colour: oklch
Since 2023, oklch() has near-universal browser support. It is similar in concept to HSL but uses a perceptually uniform colour space — meaning equal steps in Lightness produce equal changes in perceived brightness (which is not true of HSL). For accessible colour scales and gradients, oklch() is now the recommended modern choice over HSL. Example: oklch(0.64 0.2 30) — Lightness 0–1, Chroma (like saturation), Hue 0–360°.