Hex colour codes explained
A hex colour is three numbers wearing an unfamiliar costume. Once you can read one digit pair, you can read them all.
Base 16 in one paragraph
Decimal uses ten digits, 0 through 9. Hexadecimal uses sixteen, so after 9 it continues with letters: a=10, b=11, c=12, d=13, e=14, f=15. Two hex digits therefore cover 0 to 255, because the first digit counts sixteens and the second counts ones. ff is 15×16 + 15 = 255. 80 is 8×16 + 0 = 128.
Reading a colour
#4287f5 splits into three pairs:
| Pair | Hex | Decimal | Channel |
|---|---|---|---|
42 |
4×16 + 2 | 66 | Red |
87 |
8×16 + 7 | 135 | Green |
f5 |
15×16 + 5 | 245 | Blue |
So #4287f5 is rgb(66 135 245) — not much red, a moderate amount of green, nearly maximum blue. A bright blue, which is exactly what it is.
Shortcuts worth memorising
Once these are in your head you can sight-read most hex codes:
00is none,ffis maximum,80is about half- All three pairs equal means a grey:
#333333,#808080,#cccccc - Higher in one channel means that hue dominates
- Raising all three pairs equally lightens; lowering darkens
Some familiar values: #ff0000 red, #00ff00 green, #0000ff blue, #ffff00 yellow (red plus green), #00ffff cyan, #ff00ff magenta.
The shorthand form
Three digits expand by doubling each one. #f00 becomes #ff0000; #a3c becomes #aa33cc. This only works for colours whose pairs happen to repeat, so it is a convenience rather than a general shortening — there is no three-digit way to write #4287f5.
Alpha
A fourth pair adds transparency, with 00 fully transparent and ff fully opaque:
color: #ff000080; /* red at about 50% opacity */
color: #f008; /* the same thing in shorthand */
Here is the trap. CSS puts alpha last. Android, Flutter and .NET put it first, and usually write it with a 0x prefix:
Color(0xFFFF0000) // Flutter: opaque red, alpha first
#ff0000ff /* CSS: opaque red, alpha last */
Same eight digits can mean different colours depending on the convention. When you paste an eight-digit value into the picker, both readings are offered so you can pick the right one.
Writing one by hand
To convert a decimal channel to hex, divide by 16 for the first digit and take the remainder for the second. For 200: 200 ÷ 16 = 12 remainder 8, and 12 is c, giving c8.
In practice nobody does this — you use a tool. But knowing it makes hex codes feel like numbers rather than magic strings.
What hex cannot do
Hex is compact and universally understood, and that is the extent of its virtues.
It cannot express colours outside sRGB, so a vivid Display P3 colour has no hex representation. It gives you no perceptual handle: there is no way to look at #4287f5 and know how to make it 10% lighter without changing its character. And it quantises to 8 bits per channel, which is enough for display but not for intermediate calculations.
For those jobs, oklch() is the better tool — see the OKLCh guide. For everything else, hex is fine and will outlive us all.
Questions
Why are hex colours six digits?
Three channels of one byte each. One byte holds 0–255, which takes exactly two hexadecimal digits, so three channels need six digits. That gives 16,777,216 possible colours.
Is #FFF the same as #FFFFFF?
Yes. The three-digit shorthand doubles each digit, so #FFF expands to #FFFFFF and #A3C expands to #AA33CC. Only colours whose channel pairs both repeat can be written in shorthand.
Does capitalisation matter in hex colours?
No. #FF0000 and #ff0000 are identical. Lowercase is more common in CSS, uppercase in code that also uses 0x literals. Pick one and be consistent.
More guides
- sRGB vs linear colour in shadersWhat display (sRGB) and linear colour numbers mean, which to use in shaders and lighting, and how Unity, Unreal and the web treat the same hue.
- OKLCh explained, and why HSL keeps letting you downHow OKLCh works, why its lightness matches what you see when HSL lightness does not, and how to use it to build tonal scales that actually look even.
- Choosing accessible text coloursHow WCAG 2 contrast ratios work, where they go wrong, what APCA does differently, and a practical method for picking text colours that pass and look right.