Why Hex Colors Use 6 Characters (and What Each Pair Means)
You've probably seen something like #3a7bd5 in a CSS file and thought, "okay, sure, that's blue somehow." But have you ever stopped and wondered — why exactly six characters? Why not five? Why not ten? And what is that #fff shorthand doing that the full six-character version can't?
I'll be honest with you. The first time I encountered hex colors I just accepted them as magic. Copy from the color picker, paste into the stylesheet, move on. It wasn't until I started doing front-end work seriously that I realized the structure of a hex code is actually one of the most elegant pieces of design in everyday computing. Once it clicks, you can read a hex color like a sentence.
Let's Talk About Paint First
When you mix paint colors as a kid, you learn that red, yellow, and blue are the "primary" colors. Screens work differently. Monitors, phones, and TVs mix red, green, and blue light (RGB) — and by blending different intensities of these three, they can produce basically any color you can see.
Think of it this way: your screen is covered in millions of tiny dots called pixels. Each pixel has three microscopic light sources — a red one, a green one, and a blue one. When you turn all three up to full blast, you get white. When you turn them all off, you get black. Every other color is some combination in between.
So the only question is: how bright should the red, green, and blue be?
The answer is a number between 0 (totally off) and 255 (maximum brightness). And that's exactly what a hex color stores — three numbers, one for each color channel.
Where Does 255 Come From?
Before we get to the hex part, let's explain 255. Computers store data in bits, and a single byte is made up of 8 bits. With 8 bits, you can represent any number from 0 to 255 — that's 256 possible values (2 to the power of 8). Color designers decided one byte per channel was enough precision for the human eye to perceive smooth color gradations, and they were right. So each of the three light channels (R, G, B) gets one byte, giving us a range of 0–255.
That means a full RGB color can be described as three numbers, like:
rgb(255, 0, 0)— pure red (red maxed out, green and blue off)rgb(0, 255, 0)— pure greenrgb(0, 0, 255)— pure bluergb(255, 165, 0)— orange
CSS actually supports this rgb() notation directly. But hex codes are a more compact way to write the same information — and they come from a number system called hexadecimal.
Hex: The Base-16 Number System
Normal counting is base-10. You have ten digits: 0 through 9. When you run out of digits, you roll over to two-digit numbers: 10, 11, 12...
Hexadecimal is base-16. You have sixteen digits: 0 through 9, then A, B, C, D, E, F (where A=10, B=11, C=12, D=13, E=14, F=15). When you run out of those, you roll over: 10 (which equals 16 in decimal), 11 (which equals 17), and so on.
Here's the key insight: any number from 0 to 255 can be written using exactly two hexadecimal digits. The highest two-digit hex number is FF, which equals 255. That's not a coincidence — it's the whole reason hex is used here. Two hex digits map perfectly onto one byte.
So if you want to express the red value 255 in hex, you write FF. If you want to express 0, you write 00. And 128 becomes 80. (If you want to verify: 8×16 + 0 = 128. Yep.)
The Six-Character Structure: RR GG BB
Now it all falls into place. A hex color code is just three two-digit hex numbers, one after another, with a # prefix to signal "this is a hex color":
#RR GG BB
^^ ^^ ^^
| | blue (0–255)
| green (0–255)
red (0–255)
Let's decode a real example. Take #FF6B35:
FF= 255 in decimal → red channel at full brightness6B= 107 in decimal → green channel at moderate brightness35= 53 in decimal → blue channel fairly dim
Put that together and you get a warm orange-red. Lots of red, some green to push it toward orange, very little blue. Makes sense visually, right?
Try another: #1A1A2E. The red is 1A (26), green is 1A (26) too, and blue is 2E (46). Three low values, but blue is the highest — so this is a very dark navy, almost black with a blue tint. That's the kind of color you'd use for a dark-mode background.
Once you internalize the RR-GG-BB structure, you start to "feel" colors from their hex codes. High FF values early in the code? Reddish. High values at the end? Bluish. All three pairs equal? Shades of gray (because equal amounts of R, G, and B always produce gray — #808080 is pure medium gray).
The #fff Shorthand — Why It Works
You've probably seen three-character hex codes like #fff or #000 or #f0a and wondered if that's a different system. It's not — it's a shorthand that only works when each pair of digits is the same letter repeated.
The rule is simple: if each channel's two digits are identical, you can drop one of them. So:
#ffffff→#fff(white — all channels at max, FF FF FF)#000000→#000(black — all channels at zero, 00 00 00)#ff0000→#f00(red — FF for red, 00 for green, 00 for blue)#aabbcc→#abc
When a browser sees #f0a, it expands it to #ff00aa — just doubling each digit. So the three-character shorthand is purely a convenience. It doesn't give you new colors; it just saves typing when you happen to be working with colors whose channel values are perfect doubles like 00, 11, 22... AA, BB, CC... FF.
This is why you can't shorten #3a7bd5 — the pairs (3a, 7b, d5) don't have repeated digits, so there's no shorthand equivalent. You're stuck with all six characters, which is fine.
How a Color Picker Generates These Numbers
When you drag the little circle around a color wheel in Photoshop or Figma or your browser's dev tools, the color picker is quietly converting your position into three 0–255 values and then converting those values into hex. You're not doing the math, but the math is happening. Every color on that wheel corresponds to a unique (R, G, B) triple, and therefore a unique six-character hex code.
There are about 16.7 million possible hex colors (256 × 256 × 256 = 16,777,216). Your screen probably can't display a noticeable difference between many of them — the human eye is more limited than the math — but they all exist as valid codes.
A Quick Trick for Reading Hex Colors at a Glance
Here's something practical you can use right now. When you're looking at a hex color and want a rough sense of what it is without a color picker:
- Split it into three pairs:
#4CAF50→ 4C / AF / 50 - Ask yourself which pair is highest. AF (175 in decimal) is the biggest here.
- The biggest value is the dominant color. Green is dominant → this is a shade of green. (It's actually Material Design's standard green, used in a lot of Android apps.)
- If two pairs are close together and one is very low, that low channel is doing very little.
#4CAF50has red at 76, green at 175, blue at 80. Green wins clearly, blue and red are both moderate. So it's a medium green that leans slightly cool.
It's not a perfect science and you won't identify exact hues this way, but it's surprisingly useful for skimming through stylesheets.
What About Opacity? The 8-Character Version
Modern CSS also supports an 8-character hex code like #3a7bd580. The last two characters are a fourth channel for opacity (called alpha), where 00 is fully transparent and FF is fully opaque. So #3a7bd580 is that same blue color at 50% transparency (because 80 in hex is 128 in decimal, which is about halfway to 255).
You won't see 8-digit hex codes as often as the 6-digit kind, but they're valid and increasingly well-supported. The structure is just RR GG BB AA.
The Bigger Picture
Hex colors are a beautiful example of how number bases solve real-world problems. Hexadecimal feels abstract until you realize it exists specifically because two hex digits = one byte = one color channel. The whole system lines up perfectly. Six characters for three channels, each channel storing a byte's worth of precision. No waste, no ambiguity.
Next time you see a hex code in a stylesheet, you'll know you're not looking at gibberish. You're looking at three carefully packed numbers that tell a pixel exactly how to glow. And that's genuinely kind of cool.