A hex colour is not a different colour system. It is the same three numbers an RGB triple carries — red, green and blue, each from 0 to 255 — written in base 16 so that each channel takes exactly two characters.
That is why the two convert with no loss and no rounding in either direction. #FF8000 and rgb(255, 128, 0) are the same instruction to the same screen.
Why two digits per channel?
Because one hex digit holds sixteen values and a channel needs 256. Two digits give 16 × 16, which is exactly the range one byte covers, so the notation lines up with how the value is stored.
Three channels of two digits gives six characters, and 256 × 256 × 256 is 16,777,216 colours. That number is the ceiling of eight-bit-per-channel colour, and it is the reason the same figure appears in monitor specifications.
Case does not matter — #ff8000 and #FF8000 are identical — and the leading hash is punctuation rather than data.
What does the three-digit form actually mean?
Each digit is doubled. #F00 expands to #FF0000 and #ABC expands to #AABBCC, so the shorthand is not a rounding of the long form but a strict subset of it.
| Shorthand | Expands to |
|---|---|
| #FFF | #FFFFFF |
| #000 | #000000 |
| #F00 | #FF0000 |
| #ABC | #AABBCC |
That subset holds 16 × 16 × 16 colours, or 4,096. Any colour whose channel pairs are not both the same digit — #FE0000, for instance — has no three-digit form at all, which is why a shortened hex sometimes refuses to shorten.
The four- and eight-digit forms add an alpha channel on the end using the same rule, so #FF000080 is red at roughly half opacity.
Reading a hex value by eye is a skill worth ten seconds. The first pair is red, the second green, the third blue — so #CC3333 is mostly red, #333333 is a dark neutral because all three pairs match, and any value whose three pairs are equal is grey by definition. A pair of FF means that channel is at full strength and a pair of 00 means it is off entirely.
Why is darkgray lighter than gray?
Because the named colours were inherited rather than designed. CSS took its list from the X11 window system by way of SVG, and in that list gray is #808080 while darkgray is #A9A9A9 — genuinely the lighter of the two.
There are around 150 of these names, both spellings of grey work throughout, and the newest one has a story: rebeccapurple was added in 2014 in memory of Rebecca Meyer, the daughter of one of the people who wrote the CSS specifications.
Names are convenient for a quick sketch and poor for a design system. They are unevenly spaced, they cannot be adjusted, and nothing about "lightgoldenrodyellow" tells you where it sits relative to anything else.
When is HSL the better notation?
Whenever you want to change a colour rather than state one. Hue is an angle from 0 to 360, saturation and lightness are percentages, so making something lighter is one number rather than three.
It is also how every palette relationship is expressed. Complementary means adding 180 to the hue; a set of tints is one hue at rising lightness. None of that is visible in a hex triple.
The catch is that HSL lightness is arithmetic, not perception. Yellow and blue at the same stated lightness look nothing alike in brightness, because the eye is far more sensitive to green than to blue — which is the reason newer notations built for perceptual evenness exist and why a scale built in HSL needs checking rather than trusting.
What should end up in the stylesheet?
Variables, not literals. A colour written once and referenced by name can be adjusted in one place, and the name records what the colour is for rather than what it looks like.
The useful naming is by role — surface, border, text, accent — because that survives a rebrand. Naming a variable after the colour itself produces the situation where a variable called blue holds a green.
Generating the variable block from a picked colour also keeps the notation consistent, which matters more than which notation you pick. Mixed hex and rgb and named colours in one file is where the near-duplicates come from.
Questions people ask
Why do designers write hex and developers write variables? A hex value is a fact about one colour; a variable is a decision about where it is used. Both belong in the file, at different layers.
Do the two forms ever differ on screen? No. They resolve to the same channel values before anything is drawn.
Why does my hex look different in print? Print is subtractive and uses four inks. A screen colour outside that range is approximated, and the bright ones are the ones that shift.
Is the alpha channel widely supported? The eight-digit form is well supported now. The separate function form remains the more conservative choice.
How do I get the hex from an image? Pick from the image directly rather than matching by eye — compression can shift a flat area by a few values.
Write it once and convert as needed. The colour picker gives every notation for one colour at a time, hex to RGB and RGB to hex do the round trip, colour name to hex and hex to colour name handle the inherited list, and the CSS colour variables generator turns a set of picks into a block you can paste.