Color codes explained: HEX, RGB and HSL
A color code is a numeric way of describing a color so that computers, browsers and design apps all display exactly the same shade. The three formats you will meet most often on the web are HEX (#FF5733), RGB (rgb(255 87 51)) and HSL (hsl(11 100% 60%)). All three examples describe the same color, a vivid reddish orange; only the notation changes.
In practice, HEX and RGB tell the screen how much red, green and blue light to emit, while HSL describes the color the way people think about it: which hue it is, how vivid it is and how light it is. This guide shows you how to read each format, how to convert between them by hand and how to pick the right one for CSS, UI design and brand work.
What a color code is and why it matters
Every modern screen builds colors from tiny red, green and blue light sources. A color code is the instruction that sets the intensity of each of those three channels. Because the instruction is numeric, nothing is left to interpretation: the designer who picks #4169E1 in Figma, the developer who pastes it into a stylesheet and the browser that renders it are all talking about the same royal blue.
Behind every code there is a color space, which defines exactly which red, green and blue the maximum value of each channel refers to. On the web the default is sRGB: whenever you write a HEX value, rgb() or hsl() without specifying another space, the browser treats it as sRGB. That is also why the same code can look slightly different on two monitors: the number is identical, but each display's calibration and capabilities differ.
With 8 bits per channel, each component ranges from 0 to 255, giving 256 × 256 × 256 = 16,777,216 combinations. That is where the familiar “16.7 million colors” figure comes from.
How to read a HEX color code
HEX (short for hexadecimal) is the most common format in CSS, brand guidelines and design tools. It starts with # followed by six digits from 0 to 9 and A to F. The six digits form three pairs:
- 1st pair: red (R);
- 2nd pair: green (G);
- 3rd pair: blue (B).
Each pair is a base-16 number. The left digit is worth 16 times its value and the right digit is worth its own value, where A = 10, B = 11, C = 12, D = 13, E = 14 and F = 15. So 00 is 0 (channel off) and FF is 15 × 16 + 15 = 255 (channel at full strength). A few examples:
-
#FF0000: red at maximum, green and blue off, which is pure red; -
#000000: everything off, black; -
#FFFFFF: everything at maximum, white; -
#808080: all three channels at 128, a mid gray. Whenever the three pairs match, you get a neutral gray.
HEX codes are case-insensitive: #ff5733 and #FF5733 are the same color. Picking one convention for a project makes the codebase easier to search.
Shorthand: #RGB
When each pair consists of two identical digits, you can shorten the code to three digits and the browser doubles each one: #F80 becomes #FF8800 , and #FFF becomes #FFFFFF. A code like #FF5733 has no shorthand, because 57 is not a repeated pair.
Transparency: #RRGGBBAA and #RGBA
CSS accepts a fourth pair for the alpha channel (opacity). 00 is fully transparent and FF is fully opaque. In #FF573380, the pair 80 equals 128, and 128 ÷ 255 ≈ 50.2% opacity. The four-digit shorthand follows the same logic: #F538 is the same as #FF553388. Some older design apps don't recognize alpha in HEX; in that case, use rgb() with alpha.
How RGB color codes work
RGB writes the same three channels as HEX, but as decimal numbers from 0 to 255. In current CSS, the recommended syntax separates the values with spaces:
.highlight { color: rgb(255 87 51); }
.overlay { background: rgb(0 0 0 / 60%); }
.badge { background: rgb(255 87 51 / 0.5); }
The slash / introduces alpha, which you can write as a percentage (50%) or a decimal (0.5). The legacy comma syntax, rgb(255, 87, 51) and rgba(255, 87, 51, 0.5), still works in every browser and is all over existing codebases. Today rgba() is simply an alias of rgb(), which already accepts alpha.
RGB is an additive model: adding light makes things brighter. All three channels at maximum give white; all three at zero give black. Red plus green produces yellow (rgb(255 255 0)), which surprises anyone who learned to mix paint in school. That difference between light and pigment is covered in the RGB vs CMYK guide.
HSL: hue, saturation and lightness
HSL describes a color with three properties that make sense to the human eye:
- Hue: an angle from 0° to 360° on the color wheel. 0° is red, 60° is yellow, 120° is green, 180° is cyan, 240° is blue and 300° is magenta. At 360° the wheel wraps back to red.
- Saturation: from 0% to 100%. At 0% the color becomes gray; at 100% it is as vivid as possible.
- Lightness: from 0% to 100%. 0% is always black, 100% is always white and 50% gives the purest version of the hue.
In CSS, the modern syntax also uses spaces: hsl(11 100% 60%) or, with transparency, hsl(11 100% 60% / 50%). The big advantage is that you can adjust a color by changing a single number. Keep the hue at 11° and saturation at 100%, then vary lightness to build a scale:
-
hsl(11 100% 40%)=#CC2500, darker, good for a button's hover state; -
hsl(11 100% 60%)≈#FF5733, the base color; -
hsl(11 100% 80%)=#FFAC99, lighter; -
hsl(11 100% 95%)=#FFEAE5, almost white, handy as an alert background.
With HEX, the same scale would mean recalculating all three pairs at every step. That is why HSL is so popular for building variations of a color palette.
HSL is not the same as HSV (or HSB)
Photoshop and many color pickers show HSB or HSV (hue, saturation, brightness/value). The hue is the same, but the vertical scale is different: in HSB, 100% brightness with 100% saturation is the pure color, while in HSL the pure color sits at 50% lightness. So don't copy numbers from one model into the other. CSS has no hsv() function, so convert to HSL, RGB or HEX before moving the color into code.
How to convert between HEX, RGB and HSL
A color converter does all of this instantly, but knowing the math helps you double-check values and spot typos.
HEX to RGB
Split the code into pairs and convert each one to decimal (left digit × 16 + right digit). For #FF5733:
FF → 15 × 16 + 15 = 255
57 → 5 × 16 + 7 = 87
33 → 3 × 16 + 3 = 51
#FF5733 = rgb(255 87 51)
RGB to HEX
Go the other way: divide each value by 16. The whole-number quotient is the first digit and the remainder is the second. For royal blue, rgb(65 105 225):
65 ÷ 16 = 4, remainder 1 → 41
105 ÷ 16 = 6, remainder 9 → 69
225 ÷ 16 = 14, remainder 1 → E1
rgb(65 105 225) = #4169E1
RGB to HSL
The standard formula works with channels on a 0 to 1 scale. Here it is step by step with rgb(255 87 51):
- Divide each channel by 255: R = 1, G ≈ 0.341, B = 0.2.
- Find the largest (max = 1) and smallest (min = 0.2) value. The difference is d = 0.8.
- Lightness: L = (max + min) ÷ 2 = 0.6 → 60%.
- Saturation: if d = 0, the color is gray and S = 0. Otherwise, S = d ÷ (1 − |2L − 1|) = 0.8 ÷ 0.8 = 1 → 100%.
- Hue: depends on which channel is largest. If it's R, H = 60 × ((G − B) ÷ d), adding 360 if the result is negative; if it's G, H = 60 × ((B − R) ÷ d + 2); if it's B, H = 60 × ((R − G) ÷ d + 4). Here R is largest: H = 60 × (0.141 ÷ 0.8) ≈ 10.6 → 11°.
Result: hsl(11 100% 60%). Notice the rounding: the exact hue is 10.6°, and if you convert hsl(11 100% 60%) back you get #FF5833, one unit off in the green channel. It's invisible, but it explains why a round trip between formats doesn't always return the original HEX. When fidelity matters, as with a brand color, keep the HEX or RGB value as your source of truth.
Which format to use: comparison table
| Format | Example | Strengths | Best for |
|---|---|---|---|
| HEX | #FF5733 | Compact, easy to copy and paste, accepted by virtually every tool | Brand guidelines, design handoff, fixed colors in CSS |
| HEX with alpha | #FF573380 | Transparency without switching formats | Shadows and overlays in projects that already use HEX |
| RGB | rgb(255 87 51) | Readable decimal values, clear alpha with / | Transparency, color manipulation in JavaScript, canvas |
| HSL | hsl(11 100% 60%) | Intuitive control over lightness and intensity | Tint and shade scales, button states, themes and CSS variables |
| CSS name | tomato | Readable in prototypes | Quick tests and teaching examples |
A common setup in real projects: store brand colors in HEX, declare them as CSS custom properties and reach for rgb() or hsl() when you need transparency or a lightness variation.
Other formats you will run into
CSS named colors
CSS defines more than 140 color names, such as navy, teal and tomato. Each name maps to a fixed HEX value: navy is #000080 (navy blue) and teal is #008080 (teal). They're handy for tests but too limited for a distinctive brand.
CMYK
CMYK (cyan, magenta, yellow and black) is the model used for print, not screens. There is a simple mathematical conversion that gives #FF5733 ≈ cmyk(0%, 66%, 80%, 0%), but what actually comes off the press depends on the color profile, the paper and the printer. CSS does not use CMYK to display colors on screen.
OKLCH and other modern color spaces
CSS Color Level 4 introduced functions such as oklch(), lab() and color(), which can reach colors outside sRGB on wide-gamut displays and have a lightness value that better matches human perception. In HSL, a yellow and a blue at the same 50% lightness look very different in brightness; OKLCH fixes that. The modern CSS colors guide covers these formats in depth.
Common color code mistakes
- Leaving out the
#in CSS.color: FF5733;is invalid and the browser drops the declaration. - Typing the letter O instead of zero. Hexadecimal only allows 0 to 9 and A to F.
#FFO000is not a color. - Using five or seven digits. Valid lengths are 3, 4, 6 or 8 digits.
- Mixing up HSL and HSB. Copying “100% brightness” from an HSB picker into
hsl()gives you white. - Expecting print to match the screen. For printed materials, ask your print shop for their color profile and request a proof.
- Choosing colors by their codes alone. Two shades can look great side by side and still lack enough contrast for text. Check them with a contrast checker.
Summary and next steps
HEX, RGB and HSL are three ways of writing the same information. HEX is compact and universal, RGB spells out the channels in decimal and handles transparency well, and HSL makes it easy to create variations of a color.
To put this into practice:
- Find the code of any color in a photo or screenshot with the image color picker.
- Convert values between HEX, RGB, HSL and CMYK with the color converter.
- Blend two colors and get the code of the result with the color mixer.
- Learn how hues are organized on the color wheel in the color theory guide.
- Browse codes, shades and combinations for each hue in the color library.