RGB to Hex Converter

#FF5733

RGB Channel Values (0-255)

Type a value or drag the slider for each color channel

Quick presets

Conversion Formula

hex = R.toString(16).padStart(2, '0')
    + G.toString(16).padStart(2, '0')
    + B.toString(16).padStart(2, '0')

R: 255FF, G: 8757, B: 5133 → #FF5733

Convert Hex to RGB Instead

Hex Color Code

#FF5733

Channel Breakdown

Red255 (100%)
Green87 (34%)
Blue51 (20%)

RGB

rgb(255, 87, 51)

HSL

hsl(11, 100%, 60%)

CMYK

cmyk(0%, 66%, 80%, 0%)

Nearest CSS Named Color

Tomato

#FF6347 — distance: 23.3

CSS Code Snippets

color: #FF5733;
color: rgb(255, 87, 51);
color: hsl(11, 100%, 60%);
background-color: #FF5733;

Common RGB to Hex Quick Reference

ColorRGBHexPreview
Red255, 0, 0#FF0000
Green0, 128, 0#008000
Blue0, 0, 255#0000FF
White255, 255, 255#FFFFFF
Black0, 0, 0#000000
Yellow255, 255, 0#FFFF00
Cyan0, 255, 255#00FFFF
Magenta255, 0, 255#FF00FF
Orange255, 165, 0#FFA500
Coral255, 127, 80#FF7F50
DodgerBlue30, 144, 255#1E90FF
Tomato255, 99, 71#FF6347

Click any row to load it into the converter above

How to Use This Tool

  1. 1.Enter values from 0 to 255 for each color channel — type directly in the number fields or drag the sliders
  2. 2.Read the hex code instantly from the blue result panel — it updates live as you adjust any channel
  3. 3.Check the color preview banner at the top to confirm the color matches your intent
  4. 4.Click "Copy" next to any format (hex, RGB, HSL, CMYK, or CSS snippets) to copy it to your clipboard
  5. 5.Try the preset buttons or reference table for common colors — click any table row to load those values

Rate this tool

From Decimal Channels to Hex Strings: Why RGB-to-Hex Matters in Every Color Workflow

An RGB to hex converter takes three decimal channel values — red, green, and blue, each between 0 and 255 — and encodes them as a single 6-character hexadecimal string that CSS, HTML, and design tools understand natively. You're eyedroppering a color from a screenshot, your OS hands you rgb(37, 99, 235), and you need #2563EB for a Tailwind config or Figma token file. The math? Divide each channel by 16, map quotient and remainder to hex digits, and concatenate. But there are edge cases around rounding, clamping, and shorthand detection that trip up even experienced developers.

RGB to Hex conversion diagram showing three decimal value sliders for red, green, and blue channels feeding into a hexadecimal color code output with color swatch comparison

The Decimal-to-Hex Formula: Division and Remainders

Each RGB channel is a number from 0 to 255. To convert one channel to its two-digit hex representation:

First hex digit = floor(value / 16)
Second hex digit = value mod 16

Both results sit in the 0-15 range, and you map 10-15 to the letters A-F. Take the value 165: floor(165 / 16) = 10, which is A. 165 mod 16 = 5. Result: A5. For a channel value of 0, both digits are 0, giving 00. For 255, both are 15 (F), giving FF.

In JavaScript, value.toString(16) does this in one call — but it returns a single character for values under 16. That's why every implementation pads with .padStart(2, '0'): the channel value 9 must become 09, not just 9, or your 6-digit hex string turns into 4 or 5 characters and breaks.

Three Conversions Walked Through

Example 1: RGB(255, 87, 51) → a warm burnt orange

  • Red 255: floor(255/16) = 15 → F, 255 mod 16 = 15 → F. Hex pair: FF
  • Green 87: floor(87/16) = 5 → 5, 87 mod 16 = 7 → 7. Hex pair: 57
  • Blue 51: floor(51/16) = 3 → 3, 51 mod 16 = 3 → 3. Hex pair: 33
  • Result: #FF5733

Example 2: RGB(37, 99, 235) → a medium blue (Tailwind blue-600)

  • Red 37: floor(37/16) = 2, 37 mod 16 = 5 → 25
  • Green 99: floor(99/16) = 6, 99 mod 16 = 3 → 63
  • Blue 235: floor(235/16) = 14 → E, 235 mod 16 = 11 → B → EB
  • Result: #2563EB

Example 3: RGB(0, 128, 128) → teal

  • Red 0: both digits are 0 → 00
  • Green 128: floor(128/16) = 8, 128 mod 16 = 0 → 80
  • Blue 128: same calculation → 80
  • Result: #008080

Notice that teal's red channel is zero while green and blue are equal at 128 — exactly half-brightness. That equal split is what gives teal its balanced, cool character compared to pure cyan at RGB(0, 255, 255) = #00FFFF.

When RGB Beats Hex (and Vice Versa)

Both formats encode the same 16,777,216 colors (256³). The question isn't accuracy — it's workflow fit.

ScenarioBetter FormatWhy
CSS stylesheets and design tokensHex7 characters vs. up to 18 for rgb(); Figma and Sketch export hex by default
JavaScript Canvas getImageData()RGBReturns a Uint8ClampedArray of R, G, B, A byte values directly
Programmatic color blendingRGBAveraging channels is trivial: (r1 + r2) / 2 — no hex parsing needed
Git diffs and code reviewHexShorter strings mean smaller diffs; pattern stands out in code scans
Accessibility contrast checksRGBThe WCAG 2.1 relative luminance formula takes linear RGB inputs, not hex
Sharing colors with designersHexUniversal shorthand everyone recognizes; fits in a chat message cleanly

A practical rule: write hex in your stylesheets, use RGB when doing math. Our hex to RGB converter handles the reverse translation when you need to go back.

Shorthand Hex: Which RGB Values Qualify?

CSS allows a 3-digit hex shorthand where each character doubles: #F80 expands to #FF8800. An RGB value qualifies for shorthand only when each channel's hex pair has two identical digits.

The decimal values that produce double-digit hex pairs are: 0 (00), 17 (11), 34 (22), 51 (33), 68 (44), 85 (55), 102 (66), 119 (77), 136 (88), 153 (99), 170 (AA), 187 (BB), 204 (CC), 221 (DD), 238 (EE), and 255 (FF). That's 16 values per channel, so only 16³ = 4,096 of the 16.7 million possible colors have a shorthand form.

Quick math check: every value in that list is a multiple of 17. So the shorthand test is simply: does value % 17 === 0 for all three channels? RGB(255, 0, 51) passes (255/17 = 15, 0/17 = 0, 51/17 = 3) and shortens from #FF0033 to #F03. RGB(255, 87, 51) fails because 87 / 17 = 5.12 — not a whole number.

Clamping and Rounding Traps

RGB channels are integers from 0 to 255. But you'll encounter fractional values from color math libraries, CSS oklch() output, and image processing pipelines that work in 0-1 float ranges.

The rounding trap. Say you multiply 0.502 × 255 and get 128.01. Truncating gives 128 (#808080). Rounding gives 128 too — same result here. But 0.498 × 255 = 126.99. Truncating gives 126 (#7E), rounding gives 127 (#7F). One digit of difference in hex means a full integer jump in the channel value. For a single pixel, that's invisible. Across a gradient of 1,920 pixels? You'll see banding artifacts if your rounding isn't consistent.

The clamping trap. Colour manipulation can push channels above 255 or below 0. Brightening RGB(200, 220, 240) by 20% gives (240, 264, 288) — two channels overflow. Without clamping to 0-255 before hex conversion, 264.toString(16) returns "108", which is three characters. Your "hex code" becomes #F0108120— 8 characters of nonsense. Always clamp first, then convert.

RGB in JavaScript, Canvas, and APIs

The Canvas 2D API's getImageData() returns pixel data as a flat Uint8ClampedArray in RGBA order: every 4 bytes represent one pixel. To extract and convert the pixel at position (x, y) on a canvas of width w:

const i = (y * w + x) * 4; const hex = '#' + [data[i], data[i+1], data[i+2]].map(c => c.toString(16).padStart(2, '0')).join('');

Note that Uint8ClampedArray automatically clamps values to 0-255, so you don't need manual bounds checking when reading from canvas. Writing tocanvas, though, doesn't benefit from this if you're building the array yourself.

REST APIs and JSON configs almost always store colors as hex strings rather than RGB arrays. A CSS Color Level 4 string takes 7 bytes (#2563EB), while an RGB JSON array takes 13+ bytes ([37,99,235]). Over thousands of color tokens in a design system, hex saves noticeable payload. That's why tools like Figma's REST API, Tailwind's config, and Material Design tokens all default to hex.

Building a Palette from RGB Channel Math

A common technique for generating a shade scale: start with a base color in RGB, then multiply each channel by a factor. For a 10-step scale from the base color RGB(37, 99, 235):

  • Shade 900 (darkest): multiply by 0.2 → RGB(7, 20, 47) → #07142F
  • Shade 700: multiply by 0.5 → RGB(19, 50, 118) → #133276
  • Shade 500 (base): multiply by 1.0 → RGB(37, 99, 235) → #2563EB
  • Shade 300: blend toward white by 50% → RGB(146, 177, 245) → #92B1F5
  • Shade 100 (lightest): blend toward white by 85% → RGB(222, 232, 252) → #DEE8FC

This linear RGB blending is quick but perceptually uneven — the middle shades tend to look muddier than you'd expect. For perceptually uniform scales, convert to HSL and adjust the lightness channel, or better yet use the oklch() color space. But for rapid prototyping, RGB channel math gives you a serviceable palette in seconds.

One gotcha: the blending formula for "blend toward white by X%" is channel + (255 - channel) * X, not channel * (1 + X). The second formula can push channels above 255 — exactly the clamping trap described above. Our color picker lets you experiment with these palettes visually if you want to compare before committing to hex values.

Marko Sinko
Marko SinkoTechnical Tools Editor

Croatian developer with a Computer Science degree from University of Zagreb and expertise in advanced algorithms. Marko builds and verifies the technical tools, number system converters, and scientific calculators across UnitCalcTools, ensuring mathematical precision and developer-friendly interfaces.

Last updated: April 13, 2026LinkedIn

Frequently Asked Questions

RGB(255, 0, 0) converts to #FF0000, which is pure red. The red channel at 255 becomes FF in hexadecimal (15 x 16 + 15 = 255), while both green and blue channels at 0 become 00. This is the brightest possible red with no green or blue mixed in.
RGB(255, 255, 255) equals #FFFFFF, which is pure white. Each channel value of 255 converts to FF in hex. When all three channels are at maximum intensity in the additive RGB model, the result is white light.
The most common cause is entering RGB values outside the 0-255 range, which gets clamped. For example, entering 300 for a channel gets capped at 255 (FF), not encoded as a larger number. Another issue is confusing the channel order: RGB is always red first, green second, blue third in the hex string.
Only when each channel converts to a hex pair with two identical digits. RGB(255, 0, 51) produces #FF0033, which shortens to #F03 because FF, 00, and 33 all have matching characters. But RGB(255, 87, 51) gives #FF5733, which cannot be shortened since 57 and 33 have different digits.
Standard RGB produces a 6-digit hex code (#RRGGBB) with no transparency. RGBA adds a fourth value for alpha (opacity), producing an 8-digit hex code (#RRGGBBAA). For instance, RGB(37, 99, 235) with 50% opacity becomes #2563EB80, where 80 in hex equals 128 in decimal, roughly half of the 0-255 opacity range.
Divide 165 by 16 to get 10 remainder 5. The quotient 10 maps to the hex digit A, and the remainder 5 stays as 5, giving you A5. So a channel value of 165 becomes A5 in the hex code. The formula is: first digit = floor(value / 16), second digit = value mod 16.
RGB(128, 128, 128) converts to #808080, which is a perfect 50% gray. When all three channels share the same value, the result is always a shade of gray. The hex digit 80 equals 128 in decimal (8 x 16 + 0 = 128), sitting exactly at the midpoint of the 0-255 range.
Check if all three channel values are within about 10-15 of each other. RGB(120, 125, 118) is a warm gray because the channels differ by only 7 points. In hex it becomes #787D76 where the pairs are close but not identical. A true neutral gray has all three channels equal, like RGB(200, 200, 200) which gives #C8C8C8.

Related Tools