On this page
- What a HEX code actually is
- Why hexadecimal instead of plain numbers
- Shorthand and alpha notation
- When to reach for HEX vs. RGB or HSL
- Reading a HEX code at sight
- The math, worked once
- Values worth memorizing
- Gotchas that bite in real code
- Where the notation came from
- Where HEX fits in a modern workflow
What a HEX code actually is
A HEX color code is a six-digit value, prefixed with a #, that represents a color the same way browsers, design tools, and image editors do internally. Each pair of digits encodes one channel of red, green, and blue on a scale from 00 to FF — that's 0 to 255 in decimal. #FF0000 is pure red: full red, no green, no blue. #000000 is black, and #FFFFFF is white.
Why hexadecimal instead of plain numbers
Hexadecimal (base 16) packs the 0–255 range for each channel into exactly two characters, using 0–9 and A–F. That's why HEX codes are always six characters long for RGB — two per channel — rather than a variable-length list like rgb(255, 0, 0). It's compact, easy to copy and paste, and has been the standard way to specify color in HTML and CSS since the early web.
Shorthand and alpha notation
When both digits in each pair match, CSS allows a three-character shorthand: #F00 is identical to #FF0000. There's also an eight-digit variant, #RRGGBBAA, where the final pair adds an alpha (transparency) channel — #FF000080 is red at roughly 50% opacity.
When to reach for HEX vs. RGB or HSL
HEX is ideal when you need to store or share an exact, unambiguous color value — in a design system, a brand guideline, or a CSS variable. RGB and HSL are usually easier to reason about when you're actively adjusting a color: HSL in particular separates hue, saturation, and lightness, which makes it simpler to create a lighter or more muted version of a color without recalculating three separate numbers. All three notations describe the same underlying color space; converting between them is lossless.
Reading a HEX code at sight
With a little practice a HEX code stops being noise and starts being a description. Read it in pairs: #FF6347 is red FF (maxed), green 63 (moderate), blue 47 (low) — a warm orange-leaning red (it's the named color tomato). A few instant patterns:
- All three pairs equal = gray.
#808080is the exact middle gray;#EEEEEEis a near-white;#111111a near-black. - One dominant pair = that hue family. High red with some green and no blue lands in oranges and yellows; high blue with some green gives teals and cyans.
- Pairs close together = muted. The closer the three channels sit to each other, the closer the color is to gray — the spread between channels is essentially saturation.
00orFFanywhere = an edge. Fully saturated colors live on the surface of the RGB cube, with at least one channel maxed or zeroed.
Paste any code into a color page to see this decomposition done for you, with every derived value alongside.
The math, worked once
Hexadecimal digits run 0–9 then A–F, so each digit carries 16 values and a pair carries 16 × 16 = 256. To decode a pair by hand, multiply the first digit by 16 and add the second: 4A → 4 × 16 + 10 = 74. Three channels of 256 values give 256³ = 16,777,216 possible six-digit codes — every one a distinct sRGB color. That's also why the shorthand form only reaches 4,096 of them (16³): #F00, expanded by doubling each digit to #FF0000, can only land on values whose pairs repeat.
Values worth memorizing
A handful of codes come up so often they're worth knowing cold: #000000 and #FFFFFF (the extremes), #FF0000 / #00FF00 / #0000FF (the pure primaries), #808080 (mid gray), and #767676 — the lightest gray that still passes WCAG AA as body text on white, which is why it appears in so many design systems. CSS also defines 148 named colors (tomato, rebeccapurple, cornflowerblue) that are nothing more than fixed HEX values with friendlier handles.
Gotchas that bite in real code
- Case never matters.
#ff6347and#FF6347are identical; pick one convention per codebase for clean diffs. - The
#is required in CSS but often stripped in URLs and config files — most tools accept both, but a bareff6347in a stylesheet is invalid. - 8-digit alpha is not a percentage. In
#RRGGBBAAthe final pair runs00–FF, so 50% opacity is80and 80% isCC— misreading80as "80%" is a classic review catch. Our alpha guide covers all the variants. - Not every six-character string is a color.
#GGGGGGis invalid — only0–9andA–Fcount.
Where the notation came from
HEX color predates CSS itself: the X Window System listed display colors as hexadecimal RGB in the 1980s, and early HTML borrowed the notation directly. It has survived every redesign of web styling since because it encodes exactly what the hardware needs — three bytes, nothing more — and because millions of documents already used it. Newer CSS syntaxes (rgb(), hsl(), oklch()) haven't replaced it so much as wrapped friendlier interfaces around the same underlying values.
Where HEX fits in a modern workflow
HEX remains the interchange format: design tools copy it, version control diffs it cleanly, and every browser and library parses it. But it's a storage notation, not a thinking notation — when you need "this color, but lighter" or an evenly spaced scale, convert to HSL or, for perceptually even results, OKLCH, do the manipulation there, and store the result back as HEX if your toolchain expects it. The converter round-trips all of these notations losslessly, and every color page shows the full set side by side.