RGB to HEX Converter
Type the three values from 0 to 255, or paste an rgb() from your CSS, and see the HEX code as you type. With transparency, you get 8-digit HEX.
Want to know if your RGB has a CSS name? Check the HTML color table with the 148 names and their values.
How to convert RGB to HEX
Converting RGB to HEX means turning each channel from decimal into hexadecimal and joining the three pairs after a #. By hand, divide the channel by 16: the quotient is the first digit and the remainder is the second.
82 = 5 × 16 + 2 → 5, 2 → 52
113 = 7 × 16 + 1 → 7, 1 → 71
255 = 15 × 16 + 15 → F, F → FF
rgb(82 113 255) → #5271FFA quotient or remainder from 10 to 15 becomes a letter: 10 is A, 11 is B, 12 is C, 13 is D, 14 is E and 15 is F. A second example, with a zero channel:
255 = 15 × 16 + 15 → FF
128 = 8 × 16 + 0 → 80
0 = 0 × 16 + 0 → 00
rgb(255 128 0) → #FF8000A zero channel still takes two digits (00). HEX with transparency, the 8-digit kind, has its own section below. And when both digits of every pair match, you can shorten the code: rgb(255 0 0) becomes #F00. The tool shows the short HEX whenever one exists.
The leading zero
The classic bug when building HEX by hand is toString(16). It does not pad with a zero: channel 15 becomes f, not 0f. With a channel like that the code loses a digit and turns into a different color, without any error:
(15).toString(16); // "f"
(15).toString(16).padStart(2, "0"); // "0f"
"#" + [15, 0, 0].map((c) => c.toString(16)).join("");
// "#f00" (and not "#0f0000")Notice that #f00 is valid short HEX, equal to #ff0000. The browser accepts it, but the color is wrong. The fix is padStart(2, '0'), which pads with a leading zero until there are two digits.
Transparency in HEX
For transparency, multiply the alpha (from 0 to 1) by 255, round it and convert the result to hexadecimal. The pair goes at the end of the code and makes the 8-digit HEX. In the field, alpha can be 0.5, .5 or 50%: all three give the same result.
alpha = 0.5
0.5 × 255 = 127.5 → 128
128 = 8 × 16 + 0 → 80
rgb(82 113 255 / 50%) → #5271FF80Why does 50% give 80 and not 7F? Because 0.5 × 255 is 127.5, and rounding goes up to 128 (80). Truncating instead of rounding lands on 127 (7F). The difference is 1 in 255, invisible on screen, but it shows up if you compare two tools byte by byte.
Going back, 8-digit HEX turns into alpha by dividing the last pair by 255 (80 gives 0.5). The HEX to RGB converter does that math and shows the ready-made rgba().
Opacity to HEX table
The pairs to put at the end of the code, from 100% to 0%, in steps of 5. The third column shows the result on top of #5271FF.
| Opacity | HEX pair | Example |
|---|---|---|
| 100% | FF | #5271FFFF |
| 95% | F2 | #5271FFF2 |
| 90% | E6 | #5271FFE6 |
| 85% | D9 | #5271FFD9 |
| 80% | CC | #5271FFCC |
| 75% | BF | #5271FFBF |
| 70% | B3 | #5271FFB3 |
| 65% | A6 | #5271FFA6 |
| 60% | 99 | #5271FF99 |
| 55% | 8C | #5271FF8C |
| 50% | 80 | #5271FF80 |
| 45% | 73 | #5271FF73 |
| 40% | 66 | #5271FF66 |
| 35% | 59 | #5271FF59 |
| 30% | 4D | #5271FF4D |
| 25% | 40 | #5271FF40 |
| 20% | 33 | #5271FF33 |
| 15% | 26 | #5271FF26 |
| 10% | 1A | #5271FF1A |
| 5% | 0D | #5271FF0D |
| 0% | 00 | #5271FF00 |
To use one, append the pair to the six-digit HEX: 40% opacity on #5271FF is #5271FF66. That works in background, color, border-color, box-shadow and even in the stops of a linear-gradient.
Convert RGB to HEX in code
In JavaScript, combine toString(16) with padStart(2, '0') so you do not lose the leading zero:
const toHex = (value) =>
Math.round(value).toString(16).padStart(2, "0");
function rgbToHex(r, g, b, a) {
const alpha = a === undefined ? "" : toHex(a * 255);
return `#${toHex(r)}${toHex(g)}${toHex(b)}${alpha}`.toUpperCase();
}
rgbToHex(82, 113, 255); // "#5271FF"
rgbToHex(82, 113, 255, 0.5); // "#5271FF80"
rgbToHex(15, 0, 0); // "#0F0000"In Python, the f-string with :02X already pads with zeros and uppercases. hex(255) returns '0xff', with a prefix and no leading zero, so the f-string is usually handier:
def rgb_to_hex(r: int, g: int, b: int) -> str:
if not all(0 <= channel <= 255 for channel in (r, g, b)):
raise ValueError("channel out of range 0-255")
return f"#{r:02X}{g:02X}{b:02X}"
rgb_to_hex(82, 113, 255) # '#5271FF'
rgb_to_hex(15, 0, 0) # '#0F0000'The trap is not validating the 0 to 255 range. Without that check, channel 300 becomes 12c, which has three digits, and the whole code comes out misaligned:
(300).toString(16); // "12c"
(-1).toString(16); // "-1"If the value comes from a text field, convert it with Number() and check it with Number.isInteger. The string "82" works, but "8 2" becomes NaN.
What CSS accepts in rgb()
The tool reads the same formats as the CSS rgb(), so you can paste straight from your stylesheet:
- Percentages:
rgb(100% 0% 0%)is the same asrgb(255 0 0). - Decimals:
rgb(82.4 113 255)is valid CSS. Here the channel is rounded to the nearest integer. - Values outside 0-255: CSS does not error, it clamps to the maximum or minimum, so
rgb(300 0 0)becomesrgb(255 0 0). The tool warns you instead, because it is almost always a typo. - Separators:
82,113,255and82 113 255both work, and a loose fourth number is read as transparency from 0 to 1.
The space and slash syntax for transparency, and how it differs from rgba() with commas, is explained in the HEX to RGB converter.
More color tools
For the opposite direction, use the HEX to RGB converter. If you need a test image with background and text colors in HEX, the dummy image generator accepts the codes you just converted.