Take #FF5733 and convert it every way, showing the arithmetic rather than just the result.
HEX to RGB is a base change. Each pair of hex digits is one byte from 0 to 255:
| Pair | Hex | Decimal |
|---|---|---|
| Red | FF | 255 |
| Green | 57 | 5 × 16 + 7 = 87 |
| Blue | 33 | 3 × 16 + 3 = 51 |
Three-digit codes are shorthand in which each digit is doubled, so #F53 means #FF5533 — a different colour from this one, which is a common source of a slightly-wrong brand shade.
First scale each channel to the range 0 to 1: R = 1.0, G = 0.3412, B = 0.2. Then
L = (max + min) ÷ 2S = delta ÷ (2 − max − min) when L is above 0.5H = 60 × ((G − B) ÷ delta) when red is the maximum channel
| Step | Calculation | Result |
|---|---|---|
| max, min, delta | 1.0, 0.2, 0.8 | — |
| Lightness | (1.0 + 0.2) ÷ 2 | 60% |
| Saturation | 0.8 ÷ (2 − 1.0 − 0.2) | 100% |
| Hue | 60 × (0.3412 − 0.2) ÷ 0.8 | 11 degrees |
So #FF5733 is rgb(255, 87, 51) and hsl(11, 100%, 60%).
K = 1 − max(R, G, B), then each ink is (1 − channel − K) ÷ (1 − K):
| Ink | Calculation | Result |
|---|---|---|
| Key (black) | 1 − 1.0 | 0% |
| Cyan | (1 − 1.0 − 0) ÷ 1 | 0% |
| Magenta | (1 − 0.3412) ÷ 1 | 66% |
| Yellow | (1 − 0.2) ÷ 1 | 80% |
This is the most important caveat on any colour converter, and most omit it. The formula above is pure arithmetic with no knowledge of ink, paper or press. Real conversion is a device transform driven by an ICC profile, because the same nominal 66% magenta lays down differently on coated stock than on newsprint, and different presses have different achievable ranges.
Worse, this particular colour is outside the printable range for most four-colour presses. Saturated oranges, vivid blue-greens and pure greens simply cannot be mixed from CMY inks at screen intensity. When you send it to print, the profile substitutes the nearest reachable colour, which is why a bright orange on screen returns as a duller brick tone. No converter can prevent that; only choosing an in-gamut colour, or a spot ink, can.
The second thing worth knowing. HSL is convenient because you can lighten a colour by raising one number, but its lightness axis is a geometric midpoint, not a perceptual one. Compare two colours that HSL says are equally light:
| Colour | HSL | Relative luminance |
|---|---|---|
| Pure yellow | hsl(60, 100%, 50%) | 0.928 |
| Pure blue | hsl(240, 100%, 50%) | 0.072 |
Both report 50% lightness; one is nearly thirteen times brighter than the other. The reason is that the eye is far more sensitive to green than to blue, which the luminance coefficients capture — L = 0.2126R + 0.7152G + 0.0722B on gamma-decoded channels — and HSL ignores entirely. So a palette built by holding HSL lightness constant will look wildly uneven.
This also explains why naive blending misfires. sRGB values are gamma-encoded, so averaging two hex codes does not average their light. The midpoint of black and white in sRGB arithmetic is #808080, which emits only about 21% of white light rather than 50%, and interpolating between complementary hues through sRGB passes through a muddy grey.
The modern answer is a perceptually uniform space. CSS now supports oklch and lab, where the lightness value does correspond to perceived lightness, so two colours at the same L genuinely look equally light and gradients interpolate without dead zones. If you are building a design system, defining your palette in oklch and converting to hex for legacy output solves the evenness problem at the source.
Contrast ratio uses the same luminance figure:
ratio = (lighter + 0.05) ÷ (darker + 0.05)
For our colour, the relative luminance works out to 0.283:
| Pairing | Ratio | WCAG result |
|---|---|---|
| #FF5733 on white | 3.15 : 1 | Fails AA body text; passes large text and UI components |
| #FF5733 on black | 6.66 : 1 | Passes AA; just short of AAA |
| Black on white | 21 : 1 | The maximum possible |
The thresholds are 4.5 to 1 for normal text, 3 to 1 for large text and interface elements, and 7 to 1 for the stricter AAA level. A vivid brand colour that fails on white is extremely common — the usual fix is to keep it for large headings, buttons and accents, and use a darkened variant for body copy.
Conversions between HEX, RGB and HSL are exact and lossless, because all three describe the same sRGB coordinates. Everything else is an approximation:
Almost always out-of-gamut clipping. Check the colour against a CMYK profile for the actual paper and press before approving artwork, and expect saturated oranges, greens and blues to shift most.
In theory they can; in practice equal parts of all three make a muddy brown, use three times the ink, and soak the paper. A dedicated black ink gives crisp text and cheaper coverage.
oklch if your targets support it, because equal lightness values look equal and tints and shades come out evenly spaced. Convert to hex for anywhere that needs it.
No. Every conversion runs in your browser and nothing you enter is transmitted or saved.
Every tool comes with a written guide, and every category is one click away.