RGB to hex
Nearest named colour: royalblue
Turns an RGB triple into the hex string CSS and every design tool expect: each channel written as two base-16 digits, so 51, 102 and 204 becomes #3366cc. The HSL and OKLCH forms of the same colour sit alongside it, with the contrast the colour gives against white and black text.
How to use the rgb to hex
The conversion happens one channel at a time and loses nothing on the way. Each of the three numbers runs 0 to 255, which is exactly the range two hexadecimal digits hold, so 51, 102, 204 is 33, 66, cc, and back again with no rounding anywhere. By hand it is a division: 204 over 16 is 12 remainder 12, and 12 is written c, so 204 is cc. Each channel stops at 255 because it is one byte, and a byte has no room for 256.
What varies is the shape of the RGB you arrived with, and three shapes turn up constantly. CSS takes both the legacy comma form, rgb(51, 102, 204), and the modern space-separated one, rgb(51 102 204), with alpha after a slash as rgb(51 102 204 / 50%). They mean the same thing, and the space form is the one to write now, because every newer colour function in CSS uses that shape. Percentages are legal too: rgb(20% 40% 80%) is a valid way to write almost the same colour, since a percentage maps onto the same 0 to 255 range rather than replacing it.
The third shape is the one that produces a wrong answer silently. Figma, SwiftUI, OpenGL, Unity and most graphics libraries hand you a channel as a float from 0 to 1 rather than an integer from 0 to 255. A value of 0.2 is not channel 2, it is 51, and pasting a float triple into a converter that expects bytes gives a colour indistinguishable from black. Multiply each by 255 and round to nearest before converting. Rounding to nearest rather than truncating matters more than it looks: truncation is how a colour drifts a step darker on every round trip through a tool chain.
Alpha is a fourth channel and it goes on the end of the hex string as a fifth and sixth digit: 80 is roughly 50 per cent, ff is fully opaque. Every current browser reads that eight-digit form. HSL and OKLCH are the two other lines shown here, and they are genuine transformations rather than a rewriting, so they can round by a step on the way back. HSL is the easy one to reason about and the one that misleads: its lightness is a position in the colour model, not a measure of how light the colour looks, so 50 per cent lightness is a vivid yellow and a deep blue at the same number. OKLCH is built so that figure means what you expect.
What people use it for
- Moving a colour out of a design tool that reports RGB into CSS
- Turning a printed brand-guideline RGB triple into a hex code
- Reading a colour from a picker that only gives channel values
- Checking a hand-typed hex code converts back to the right channels
Questions
Divide each channel by 16. The quotient is the first digit and the remainder is the second, with 10 to 15 written a to f. 204 gives 12 remainder 12, so cc; 51 gives 3 remainder 3, so 33.
Because a channel is one byte, eight bits, and 255 is all eight set. There is no room for 256, which is why an RGB value above it is a bug rather than a bright colour.
Multiply each by 255 and round to nearest, then convert. Figma, SwiftUI, OpenGL and most graphics libraries use the 0 to 1 float form, and feeding it to a converter expecting bytes returns something very close to black.
Going RGB to hex, entirely. It is the same three numbers written in base 16, so nothing is approximated in either direction. The HSL and OKLCH lines are transformations and can round by a step on the way back.
Nothing, to a browser. The commas are the legacy syntax and the spaces are the modern one, which every newer CSS colour function also uses. Write the space form in new code.
Yes. rgb(20% 40% 80%) is valid and maps onto the same 0 to 255 range, so it is a way of writing the value rather than a different scale. Mixing percentages and numbers in one colour is not allowed.
Convert the three channels as usual and append the alpha as a fifth and sixth digit: 50 per cent is 80, fully opaque is ff. Older targets that will not take eight digits want rgba() left as it is.
Hex is shorter and is what design tools hand you. rgb() is the one to use when a channel comes from a variable or a calculation, because you can put an expression in it and you cannot put one inside a hex string.
Because HSL lightness is a position in the model rather than a measure of appearance. A yellow and a blue at the same figure look nothing alike in weight. OKLCH is the format where that number means what you expect.