Colour Formats

Hex, RGB, and HSL Explained: How Colour Codes Work (and How to Convert Them)

A hex code, an rgb() value, and an hsl() value are usually three ways of writing the same colour — like 0.5, 50%, and ½. Hex and RGB encode how much red, green, and blue light to mix; HSL re-describes that mix as a hue, a saturation, and a lightness, which is far friendlier for humans making adjustments. This guide shows what each notation means, how to convert between them by hand (every example here actually computes), and which one to reach for depending on the task. For the daily grind, a free in-browser converter does the arithmetic instantly — but once you can read the codes, you'll spot bad colours before they ship.

The model underneath: three channels of light

Screens make colour by mixing red, green, and blue light. Each channel gets an intensity from 0 (off) to 255 (full). That's it — every format below is just a different spelling of those three numbers:

  • rgb(47, 107, 255) — the three intensities in plain decimal.
  • #2F6BFF — the same three numbers in hexadecimal, two digits per channel.
  • hsl(223, 100%, 59%) — the same colour described as hue 223° (a blue), fully saturated, medium-light. (That value is rounded from hsl(222.7, 100%, 59.2%) — the maths is below.)

Why 255? Each channel is one byte — 8 bits — and a byte holds 2⁸ = 256 values, 0 through 255. Three channels of 256 values gives 256³ = 16,777,216 possible colours, the "16.7 million colours" of spec sheets.

Hex codes: base-16 in disguise

Hexadecimal is base 16: digits 0–9 then A–F, where A = 10, B = 11, … F = 15. A two-digit hex number is (first digit × 16) + second digit, so each channel spans 00 (0) to FF (15 × 16 + 15 = 255).

Reading #2F6BFF by hand:

Channel Hex Arithmetic Decimal
Red 2F 2 × 16 + 15 47
Green 6B 6 × 16 + 11 107
Blue FF 15 × 16 + 15 255

So #2F6BFF = rgb(47, 107, 255) — Medley blue, as it happens. Blue is maxed, green is moderate, red is low: even without a swatch you can predict "a strong blue with a hint of violet-leaning warmth kept in check".

Three hex conventions worth knowing:

  1. Shorthand: a 3-digit code doubles each digit — #06C means #0066CC, #FFF means #FFFFFF (white). #2F6BFF has no shorthand because its pairs aren't doubled digits.
  2. Case doesn't matter: #2f6bff and #2F6BFF are identical. Pick one style and stay consistent (we write hex uppercase).
  3. Alpha: an 8-digit hex adds a fourth pair for opacity. #2F6BFF80 is Medley blue at hex 80 = 128 ÷ 255 ≈ 50.2% opacity. Gotcha: 80 is hex, so it's ~50%, not 80%.

RGB notation: the same bytes, human-readable

rgb(47, 107, 255) is the same three bytes in decimal — nothing new to learn, but two gotchas hide here:

  • Percent vs 0–255: CSS also accepts rgb(18.4%, 42%, 100%). Mixing the two scales (writing rgb(47%, 107%, 255%)) is a classic copy-paste bug — values over 100% just clip.
  • Alpha is decimal here: rgba(47, 107, 255, 0.5) — the 0.5 really is 50%, unlike hex's trailing 80.

Converting RGB→hex is the reverse of the table above: divide each channel by 16; the quotient is the first digit, the remainder the second. 47 ÷ 16 = 2 remainder 15 → 2F. Done three times, rgb(47, 107, 255) becomes #2F6BFF again.

HSL: the format made for humans

RGB answers "how much of each light?" HSL answers the questions people actually ask while adjusting a colour:

  • Hue (0–360°): where on the colour wheel — 0° red, 120° green, 240° blue, wrapping back to red at 360°.
  • Saturation (0–100%): how vivid — 0% is grey, 100% is maximally colourful.
  • Lightness (0–100%): 0% is black, 100% is white, 50% is the "pure" colour.

The magic is that each slider means something on its own. Want a lighter button hover of the same brand blue? Keep hue and saturation, raise lightness: hsl(223, 100%, 59%) → hsl(223, 100%, 75%). In hex you'd be guessing at three channels simultaneously.

Worked example: RGB → HSL by hand

Take a simple one first — rgb(255, 128, 0) (a strong orange):

  1. Scale each channel to 0–1: R = 1, G = 128 ÷ 255 = 0.502, B = 0.
  2. Max = 1, min = 0, delta = 1.
  3. Lightness = (max + min) ÷ 2 = 0.5 → 50%.
  4. Saturation (for L ≤ 50%) = delta ÷ (max + min) = 1 ÷ 1 → 100%.
  5. Hue: max is red, so H = 60° × (G − B) ÷ delta = 60° × 0.502 = 30.1° → 30° (rounded).

Result: hsl(30, 100%, 50%). Sanity check: 30° sits between red (0°) and yellow (60°) — exactly where orange belongs.

Now the harder one, #2F6BFF = rgb(47, 107, 255):

  1. Scaled: R = 0.184, G = 0.420, B = 1.
  2. Max = 1 (blue), min = 0.184, delta = 0.816.
  3. L = (1 + 0.184) ÷ 2 = 0.592 → 59%.
  4. S (for L > 50%) = delta ÷ (2 − max − min) = 0.816 ÷ 0.816 = 1 → 100%.
  5. H: max is blue, so H = 60° × (4 + (R − G) ÷ delta) = 60° × (4 + (0.184 − 0.420) ÷ 0.816) = 60° × (4 − 0.289) = 60° × 3.711 = 222.7° → 223° (rounded).

Result: hsl(223, 100%, 59%). All values above are rounded to 3 decimal places mid-calculation and to whole numbers at the end — a converter carries full precision throughout, which is one honest reason to let it do the work.

Which format when?

Task Best format Why
Copying a colour from a mockup or brand guide Hex Compact, universal, unambiguous
Generating tints/shades of one colour HSL Change lightness only, hue stays put
Adding transparency in CSS rgba()/hsla() or 8-digit hex Alpha is explicit
Reasoning about "is this warm or cool?" HSL Hue is a single readable number
Talking to any design tool or API Hex or RGB Lowest common denominator

One habit worth stealing from design systems: define a palette's hues once, then build every variant by moving lightness in HSL. Medley Web's own ink colour #0B1733 is hsl(222, 65%, 12%) — practically the same hue as the accent's 223°, just dark and muted, which is why the two always look related.

A final caution: a pretty colour is not automatically a usable one. Whatever format you work in, body text needs roughly a 4.5:1 contrast ratio against its background (the WCAG AA guideline) — a check that's math on the RGB values, and another thing a good tool computes for you in one paste.

Colour codes are one of several "same value, different notation" systems you'll meet — the same idea drives binary and hex numbers, and unit conversions generally, and even timestamps and timezones are just one moment in time wearing different formats.

FAQ

How do I convert a hex colour to RGB by hand?

Split the six digits into three pairs, then compute (first digit × 16) + second digit for each, using A=10 … F=15. #2F6BFF → 2F = 2×16+15 = 47, 6B = 6×16+11 = 107, FF = 255 → rgb(47, 107, 255).

Are hex and RGB the same thing?

Effectively yes — both encode the same red, green, and blue bytes; hex writes them in base 16, rgb() in decimal. Converting between them never changes the colour. HSL is also the same colour, re-expressed as hue, saturation, and lightness.

What does the fourth pair in an 8-digit hex code mean?

Opacity (alpha), also in hex: 00 is fully transparent, FF fully opaque. Gotcha: #2F6BFF80 is about 50% opaque (hex 80 = decimal 128, and 128 ÷ 255 ≈ 0.502), not 80%.

When should I use HSL instead of hex?

When you're adjusting rather than copying: lighter/darker variants, hover states, or building a palette around one hue. Change only the lightness or saturation and the colour stays recognisably itself — something hex makes nearly impossible to do by eye.


Got a colour code to translate right now? Medley Web is building a free hub of instant, in-browser tools — hex ⇄ RGB ⇄ HSL among them — one input in, many formats out. Convert colours free at medley-web.com.

Comments are disabled for this article.