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:
- 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.
- Case doesn't matter: #2f6bff and #2F6BFF are identical. Pick one style and stay consistent (we write hex uppercase).
- 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 (writingrgb(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):
- Scale each channel to 0–1: R = 1, G = 128 ÷ 255 = 0.502, B = 0.
- Max = 1, min = 0, delta = 1.
- Lightness = (max + min) ÷ 2 = 0.5 → 50%.
- Saturation (for L ≤ 50%) = delta ÷ (max + min) = 1 ÷ 1 → 100%.
- 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):
- Scaled: R = 0.184, G = 0.420, B = 1.
- Max = 1 (blue), min = 0.184, delta = 0.816.
- L = (1 + 0.184) ÷ 2 = 0.592 → 59%.
- S (for L > 50%) = delta ÷ (2 − max − min) = 0.816 ÷ 0.816 = 1 → 100%.
- 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.