HEX, RGB and HSL: one colour, three notations

2026-09-02·Images and page weight·3 min read·by Sourabh Singh

HEX, RGB and HSL: one colour, three notations

How hex codes map to RGB channels, why HSL is the right notation for building a palette, and how contrast ratios are actually calculated.

HEX, RGB and HSL: one colour, three notations

HEX and RGB are the same numbers in different notation - #2563eb is rgb(37, 99, 235), two hex digits per channel. HSL describes the same colour as hue, saturation and lightness, which makes generating consistent tints and shades trivial in a way HEX never is.

Every colour on the web is three numbers describing how much red, green and blue light to emit. The notations differ; the colour does not.

HEX is RGB in base 16

#2563eb is three pairs of hex digits. Each pair is one channel, 00 to ff, which is 0 to 255 in decimal.

  • 25 = 37 red
  • 63 = 99 green
  • eb = 235 blue

So #2563eb and rgb(37, 99, 235) are identical. Converting by hand is just reading each pair as base 16.

Three-digit codes are shorthand where each digit doubles: #f00 expands to #ff0000. It only reaches 4,096 colours, so it is useful for primaries and not much else.

Eight digits add alpha: #2563eb80 is that blue at roughly 50% opacity. Modern CSS also accepts rgb(37 99 235 / 50%), which does the same thing more legibly.

Free toolColor ConverterConvert HEX to RGB and back, get the HSL equivalent, and see the contrast ratio against white and black for accessibility checks.

HSL is for building palettes

HSL describes the same colour as three perceptual properties:

  • Hue - position on the colour wheel, 0 to 360 degrees
  • Saturation - how far from grey, 0 to 100%
  • Lightness - 0% is black, 100% is white, 50% is the pure hue

#2563eb is hsl(221, 83%, 53%).

The reason this matters: to generate a set of tints and shades of one colour, hold hue and saturation constant and vary lightness. hsl(221, 83%, 95%) down to hsl(221, 83%, 15%) gives a coherent ramp in one line. Doing the same in HEX means guessing at 24 hex digits and getting a ramp that drifts in hue.

Every design system that generates colour scales does it in HSL or a perceptual space like OKLCH, never in HEX.

OKLCH, briefly

HSL has a real flaw: equal lightness values do not look equally light. hsl(60, 100%, 50%) (yellow) is visibly brighter than hsl(240, 100%, 50%) (blue), despite both claiming 50%.

OKLCH fixes this by being perceptually uniform, and it is supported in every current browser. If you are building a colour system now, it is the better choice. HSL remains fine for adjusting a colour you already have.

Contrast ratios

Contrast is computed from relative luminance, which weights the channels according to how sensitive the eye is to each: red 0.2126, green 0.7152, blue 0.0722. Green dominates, which is why green text on white fails contrast checks more easily than intuition suggests.

The ratio is (lighter + 0.05) / (darker + 0.05), running from 1:1 to 21:1.

WCAG thresholds:

  • 4.5:1 - body text, AA
  • 3:1 - large text (18pt, or 14pt bold) and UI components, AA
  • 7:1 - body text, AAA

Brand colours frequently fail. A mid-tone brand blue on white often lands around 3.5:1, which passes for headings and fails for body copy. The usual fix is to darken the text variant of the brand colour and keep the original for backgrounds and accents.

Colour profiles

Screenshots and photographs are often in Display P3 or Adobe RGB, wider gamuts than sRGB. A canvas reads sRGB values, so a colour picked from a P3 screenshot will not exactly match what a design tool reports.

For web work this is rarely a problem, because the web is sRGB by default. It matters when you are matching a printed brand colour, where you want the Pantone or CMYK reference rather than a picked pixel.

Convert between notations, or lift a colour from an image, with the HEX to RGB converter and the image colour picker.

Tools from this guide