HEX to RGB Color Converter
Design tools export colors as HEX codes, but CSS functions like rgba() and linear-gradient() expect numeric RGB channels. Switching between them manually means decoding two hex digits per channel, and that decoding step is easy to get wrong under time pressure.
How the conversion works
HEX encodes each color channel as a two-digit base-16 number. Converting to RGB means translating each pair from hexadecimal to decimal: the first pair is the red channel, the second green, the third blue.1 Concretely, c8 in hex equals (12 × 16) + 8 = 200 in decimal, ff equals 255, and 00 equals 0. Because the encoding is purely positional, the conversion is exact for any standard six-digit HEX value, with no rounding or approximation.
Channel order is fixed
The six digits always map to red, green, and blue in that order. There is no header or metadata inside the string; the position alone determines the channel. This positional simplicity is what makes the conversion reliable across every programming language and browser implementation. Whether you decode the string in JavaScript, Python, or Rust, the result is identical because the format itself carries no ambiguity.
Because the channel order never changes, you can safely read just one channel from a HEX string without converting the rest. If you only need the red value, take characters 1 and 2 and convert that single pair, which is the same shortcut the CSS red() function uses internally. This fixed ordering is also why HEX survives as the default export from design tools: there is no header or flag to strip before the numeric conversion begins, so the decoding step stays simple and predictable.
Why base-16 maps cleanly to base-10
Each hex digit represents four binary bits, so two digits represent one full byte (8 bits). That is why hex pairs line up perfectly with 0–255 decimal values, and why the conversion is just a base conversion rather than a lookup or approximation. For example, the hex value 1a translates to (1 × 16) + 10 = 26 in decimal, with no rounding and no edge case to handle.
Where this comes up
Design tools export nearly every color as HEX. Figma, Sketch, and Photoshop all default to #rrggbb in their copy-as-CSS outputs. Consequently, any workflow that starts in a design application and ends in code requires the RGB form at some point, whether that code is a canvas 2D context, a WebGL shader uniform, or a Node.js server rendering PNG images. Furthermore, JavaScript's CSS Object Model exposes computed colors as rgb() strings, making RGB the natural interchange format between design pipelines and browser code.
RGB as a common interchange format
When color data moves between tools, RGB is the lowest common denominator. Design applications, image processors, and browser APIs all understand the three-channel decimal form, even if they prefer HEX or HSL internally. Converting HEX to RGB early in the pipeline avoids repeated conversions downstream and keeps color values consistent across every stage of the build. If your team updates brand colors in a single source of truth, converting once to RGB and distributing that value everywhere is far safer than re-decoding HEX strings at every consumption point.
Edge cases and rounding
Shorthand HEX values like #f50 expand before conversion: each single digit doubles to a pair, yielding #ff5500.2 An optional seventh and eighth character encode alpha on the same 00–ff scale, so #ff550080 is orange at roughly 50% opacity, where 80 hex equals 128.3 Yet the rgb() function has no alpha slot, so use rgba() for any transparent variant.4
Floating-point channels need an extra step
Floating-point channel values in the 0.0–1.0 range appear frequently in WebGL, Three.js, and shader code. To convert a HEX color to that form, first decode the hex pairs to 0–255 integers as usual, then divide each integer by 255.0. For example, #c8ff00 becomes (0.784, 1.0, 0.0). This extra division is straightforward but easy to forget, especially when your pipeline mixes integer and float color representations. In GLSL, the normalized triplet is often declared as a vec3 uniform, so forgetting the division produces colors that are far brighter than intended.
When shorthand causes confusion
Three-digit HEX (#f50) looks similar to a function call or a CSS class name at a glance. If your source data mixes shorthand and six-digit values, normalize them all to six digits before conversion so downstream code does not accidentally treat them as different colors. This is especially important when pulling colors from minified stylesheets or legacy design files where shorthand is common. A color named #fff and a color named #ffffff are identical after normalization, but raw string comparison would treat them as distinct values.
Using RGB output in canvas and WebGL contexts
Canvas 2D contexts accept RGB colors as strings: ctx.fillStyle = "rgb(200, 255, 0)" works in every browser. Yet the canvas API also accepts hex strings, HSL, and even named colors, so the practical reason to convert a design color to rgb() for canvas is consistency with an existing codebase or a team style guide that mandates rgb() notation. Building on this, if your project uses TypeScript with strict typing for color values, having the explicit rgb() form makes it easier to validate color strings at build time.
WebGL shaders require colors as normalized float triplets in 0.0–1.0 space, not as 0–255 integers.5 After converting HEX to RGB, divide each channel by 255.0 to get the float triplet your shader expects. For example, rgb(200, 255, 0) becomes vec3(0.784, 1.0, 0.0) in GLSL. Some WebGL frameworks (Three.js, Babylon.js) accept 0–255 integers and normalize internally, but the raw WebGL API does not. Converting through RGB first gives you explicit control over the normalization step, which matters when you need precise color values for lighting calculations or color grading.
HEX to RGB in server-side and build-time workflows
Server-side rendering pipelines often need HEX-to-RGB conversion at build time rather than at runtime. Node.js packages like color-convert, tinycolor2, and culori all provide HEX-to-RGB functions that return arrays of integers. If your build process generates CSS custom properties from a design token file, the conversion from HEX tokens to RGB values happens once during the build, and the resulting CSS ships the rgb() values directly to the browser without any client-side conversion.
CSS preprocessors like Sass and Less also provide HEX-to-RGB functions: red($color), green($color), and blue($color) in Sass extract individual channels. These functions are useful when you need to construct rgba() values from a HEX base: rgba(#c8ff00, 0.5) in Sass compiles to rgba(200, 255, 0, 0.5) in CSS. Building on this, PostCSS plugins can perform the same transformation at build time, converting all HEX values in your stylesheet to rgb() notation if your project convention requires it.
Color space implications: sRGB is the only safe assumption
Every HEX code encodes sRGB values. There is no HEX syntax for P3, Adobe RGB, or any other color space.6 When you convert #c8ff00 to rgb(200, 255, 0), the result is an sRGB color. If you need the same visual color in P3 space, the numeric RGB values will be different, but HEX cannot express that difference. This is a fundamental limitation of the HEX format: it is sRGB-only by definition.
CSS Color Level 4 addresses this with the color() function: color(srgb 0.784 1.0 0.0) is the explicit sRGB equivalent of #c8ff00, while color(display-p3 0.85 0.95 0.12) is a P3 color that may look similar but has different numeric values.7 Building on this, when you convert HEX to RGB and use the result in CSS, you are implicitly working in sRGB. If your design system targets P3 displays, you need a separate P3 color definition; the HEX-to-RGB conversion alone cannot get you there.
When to use this
Use this when you have a HEX color from a design file (Figma, Sketch, Photoshop) and need the rgb() or rgba() value for a CSS stylesheet or a canvas API call.
Examples
Figma brand color → CSS rgba with opacity
#c8ff00
rgb(200, 255, 0)
For rgba(), append the alpha: rgba(200, 255, 0, 0.5)
Shorthand HEX → full RGB
#f50
rgb(255, 85, 0)
- 1.
W3C, "A Standard Default Color Space for the Internet - sRGB," w3.org, November 1996. https://www.w3.org/Graphics/Color/sRGB.html
- 2.
MDN Web Docs, "<hex-color>," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/hex-color
- 3.
W3C, "CSS Color Module Level 4: Color," w3.org, accessed June 2026. https://www.w3.org/TR/css-color-4/#color
- 4.
WebGL Fundamentals, "Shaders and GLSL," webglfundamentals.org, accessed June 2026. https://webglfundamentals.org/webgl/lessons/webgl-shaders-and-glsl.html
- 5.
CSS-Tricks, "Almanac: Functions — color()," css-tricks.com, accessed June 2026. https://css-tricks.com/almanac/functions/c/color/
- 6.
Chrome for Developers, "Access more colors," developer.chrome.google.cn, accessed June 2026. https://developer.chrome.google.cn/docs/css-ui/access-colors-spaces
- 7.
IEC, "Multimedia systems and equipment — Colour measurement and management — Part 2-1: Colour management — Default RGB colour space — sRGB," IEC 61966-2-1, 1999. https://webstore.iec.ch/en/publication/6169