RGB to HEX Color Converter
CSS color pickers and browser DevTools often show colors as rgb() values. Design systems, HTML attributes, and most color palettes expect #rrggbb HEX. Converting between them by hand means doing base-16 arithmetic for each channel.
How the conversion works
Converting RGB to HEX reverses the channel-decoding process. Each decimal integer from 0 to 255 is expressed as a two-digit base-16 number, padded with a leading zero when the value is below 16. Red channel 59 becomes 3b (3 × 16 + 11), green 130 becomes 82, blue 246 becomes f6. Concatenated with a # prefix, the result is #3b82f6.1 Building on this pattern, the conversion is lossless for any integer RGB value, and no precision is dropped when the inputs are whole numbers.
Padding matters for correctness
When a channel value is below 16, the hex representation is a single digit. The leading zero padding ensures the result is always two digits per channel, which keeps the final string exactly seven characters long (including the #). Without padding, the value 5 would serialize as "5" instead of "05", producing an invalid HEX string that no browser would parse correctly.
Zero padding also keeps the mapping between channels and string positions stable, so a parser can always locate the green pair at characters 3-4 and the blue pair at 5-6. If the red channel were allowed to collapse to a single digit, every later channel would shift position and the whole decode would break. This positional guarantee is exactly why the HEX format mandates two digits per channel and why a correct converter never skips the leading zero.
Why the reverse mapping is unique
Because each 0–255 integer maps to exactly one two-digit hex pair, the RGB-to-HEX function is injective. Two different RGB triplets can never produce the same HEX output, which means the conversion is fully reversible for integer inputs and safe to use as a cache key or a deduplication token in style systems. If you store both formats side by side in a design token file, you can index by HEX and retrieve the RGB equivalent without any ambiguity or lookup table.
Where this comes up
Browser DevTools expose computed CSS colors in rgb() notation. Canvas APIs return pixel data as separate 0–255 integers. Color pickers in most JavaScript UI libraries emit {r, g, b} objects. Conversely, every HTML color attribute, most CSS property defaults, and nearly all design-tool import dialogs expect #rrggbb, which makes it easy to paste a DevTools color into a design file. Whenever data flows out of a browser environment into a design file, a spreadsheet, or a brand color registry, HEX is the format that copies cleanly without reformatting.
Copy-paste reliability across tools
HEX strings survive a round trip through email, Slack, spreadsheets, and version-control diffs without corruption. RGB values, by contrast, get reformatted by many tools (some add spaces, others wrap rgba() with different alpha syntax), which makes them harder to grep for across a codebase. If you need a color format that every tool in your chain understands without ambiguity, HEX is the safer choice.
When RGB input is the only option
Some APIs return only RGB. The getImageData() method on a canvas pixel buffer gives you four integers per pixel (r, g, b, a). If you are building a palette extractor or a color-theming widget, you will receive RGB values from the API and need to convert them to HEX before writing CSS custom properties or sharing the palette with stakeholders.
Edge cases and rounding
Integer inputs in the range 0–255 convert without loss. Values outside that range are invalid; CSS clamps them, but the resulting HEX will be incorrect.2 Floating-point RGB values, which appear frequently in libraries that store channels as 0.0–1.0, must be multiplied by 255 and rounded to integers before conversion. Alpha channels have no standard slot in 6-digit HEX, so append a seventh and eighth digit for the #rrggbbaa format, where the alpha pair uses the same 00–ff scale, with 00 fully transparent and ff fully opaque.3
Handling floating-point channel values
Libraries like Three.js and chroma.js often represent colors as normalized floats in the 0.0–1.0 range. Before converting to HEX, multiply each float by 255 and round to the nearest integer. The rounding step is critical: always rounding down (Math.floor) versus rounding to nearest (Math.round) can shift the final HEX value by one unit in either channel, which produces a visually noticeable difference on gradients.
Why out-of-range inputs break the output
If your pipeline ever produces a value below 0 or above 255, the resulting HEX string will be malformed. Negative values have no hex representation, and values above 255 require more than two digits. Validate your inputs before conversion, or clamp them explicitly, so downstream code never receives a HEX string that fails to parse. A common source of out-of-range values is arithmetic on channel values, such as boosting brightness by adding 20 to each channel without checking whether the result exceeds 255 before the conversion step.
RGB to HEX in design token pipelines
Design token systems often store colors in a format-agnostic way (as RGB objects or OKLCH coordinates) and export to multiple CSS formats at build time. When your token pipeline needs HEX output, the RGB-to-HEX conversion is the final step before writing the CSS custom property. Tools like Style Dictionary, Tokens Studio, and Theo all include HEX export as a built-in transformation.
The conversion in these tools follows the same algorithm: each 0–255 integer becomes a two-digit hex pair, padded with a leading zero for values below 16. The difference is in how they handle edge cases. Style Dictionary rounds floating-point inputs before conversion. Tokens Studio clamps out-of-range values and warns. Building on this, if you are building a custom token pipeline, decide how to handle floats and out-of-range values before the HEX conversion step, because the HEX format cannot represent fractions or values outside 0–255 per channel.
The #rrggbbaa format and browser support
CSS Color Level 4 introduced 8-digit HEX notation: #rrggbbaa, where the last two digits encode alpha on the same 00–ff scale.3 This gives you a compact way to write rgba() equivalents: #ff550080 is the same as rgba(255, 85, 0, 0.5). Browser support is excellent: Chrome 62+, Firefox 49+, Safari 10+, and Edge 79+ all parse 8-digit HEX correctly.4
Converting rgba() to #rrggbbaa requires multiplying the alpha value (0–1) by 255 and encoding it as a two-digit hex pair. An alpha of 0.5 becomes 128 in decimal, which is 80 in hex. An alpha of 1.0 becomes 255, which is ff. Building on this, the #rrggbbaa format is shorter than rgba() by several characters, which matters for large stylesheets where every byte counts. The tradeoff is readability: most developers find rgba(255, 85, 0, 0.5) easier to parse visually than #ff550080. Use the format that matches your team convention.
RGB to HEX round-trip precision in automated workflows
Automated workflows that convert RGB to HEX and back to RGB may not return the exact same values. The issue is not the HEX format itself (which is lossless for integer RGB) but the intermediate processing. If a tool normalizes RGB values to floats, converts to HEX, then converts back to RGB, the floating-point arithmetic may introduce an error of 1 in one channel.5 This is within the tolerance of human perception but can cause test failures in pixel-perfect visual regression tools.
To avoid round-trip issues in automated pipelines, store the authoritative color value in a single format (HEX or RGB) and derive the other format from it, rather than converting back and forth. If you must convert in both directions, round to the nearest integer at each step and accept that a difference of 1 in one channel is within normal floating-point tolerance. Building on this, visual regression tools like Percy and Chromatic typically allow a configurable tolerance for color differences; set it to 1–2 RGB units to avoid false positives from harmless rounding drift.
When to use this
Use this when you have an RGB value from a browser DevTools color picker, a CSS computed style, or an image processing result that you need to paste into a design file or HTML attribute.
Examples
Browser DevTools color → Figma HEX
rgb(59, 130, 246)
#3b82f6
Canvas pixel data → CSS color
rgb(255, 99, 71)
#ff6347
This is the named color "tomato".
- 1.
MDN Web Docs, "<hex-color>," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/hex-color
- 2.
W3C, "CSS Color Module Level 4: Color," w3.org, accessed June 2026. https://www.w3.org/TR/css-color-4/#color
- 3.
W3C, "CSS Color Module Level 4: Hex Notation," w3.org, accessed June 2026. https://www.w3.org/TR/css-color-4/#hex-notation
- 4.
Can I use, "#rrggbbaa hex color notation," caniuse.com, accessed June 2026. https://caniuse.com/css-rrggbbaa
- 5.
MDN Web Docs, "Number," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number