Skip to content

RGB to Hex Converter

Convert RGB to hex in your browser — integers, percentages, and rgba alpha all supported. Free, instant, no signup, your colors never leave the page.

No Tracking Runs in Browser Free
All color conversion happens locally in your browser. No data is sent to any server.
Gamut: sRGB Display P3 Rec2020
Contrast vs:
AA AA-Lg AAA AAA-Lg · APCA Lc
Color blindness simulation (8 types)
Protanopia (red-blind)
Deuteranopia (green-blind)
Tritanopia (blue-blind)
Achromatopsia (total)
Protanomaly (red-weak)
Deuteranomaly (green-weak)
Tritanomaly (blue-weak)
Achromatomaly (partial)
Tints / Shades / Tones / Harmonies

Tints

Shades

Tones

Harmonies

Copy as code
Common colors reference
Reviewed for CSS Color 4 conformance, integer + percentage + alpha RGB input support, 8-digit hex alpha emission correctness, and round-trip bit-exactness between RGB and HEX across the 0-255 range. — Go Tools Engineering Team · May 27, 2026

What Is an RGB to Hex Converter?

An RGB to hex converter is a small utility that turns three 0-255 integer channel values (`rgb(255 87 51)`) into the 6-character hex code that encodes the same color (`#FF5733`). RGB and hex are the two formats every web stylesheet, design tool, and image-pixel pipeline has been built around since the late 1990s, and the conversion between them is the single most common operation in color tooling — paired with its inverse direction, this exact transform runs millions of times per day across every Figma plugin, CSS preprocessor, design-token build, and color-picker UI on the web. RGB is the channel-addressed format that hardware APIs, canvas drawing calls, image-buffer manipulation, OpenGL color attributes, and most graphics SDKs report natively — three separate 0-255 integers that map directly to the red, green, and blue subpixels of an LCD or the phosphors of a CRT. Hex is the terse copy-paste format that Figma, Sketch, Photoshop, and every brand-guidelines PDF expect for output — a 6-character base-16 string that fits in a CSS custom property comfortably and reads at a glance once your eyes learn the patterns. Converting between them is mechanical: convert each integer to a 2-digit base-16 pair and concatenate with a leading `#`. This tool runs that conversion live as you type, with no "Convert" button to click, and surfaces every other common color format (HSL, OKLCH, OKLAB, HSV, HWB, CMYK, plus the 148 CSS named colors) alongside the HEX output for free.

**The hex format itself deserves a closer look.** Standard CSS hex comes in four legal shapes. The canonical 6-digit form `#RRGGBB` packs three 8-bit channels into 6 base-16 digits — 16,777,216 colors total (256³). The 3-digit shorthand `#RGB` is a compressed form where each digit is duplicated to form the 6-digit equivalent: `#F73` expands to `#FF7733`, *not* `#000F73` (this is one of the most-mistaken rules in CSS color syntax). The 8-digit alpha form `#RRGGBBAA` appends a 2-digit alpha pair on a 0-`FF` scale, with `00` fully transparent and `FF` fully opaque. The 4-digit alpha shorthand `#RGBA` mirrors 3-digit shorthand by duplicating each digit, including the alpha digit. Hex is case-insensitive — `#ff5733` and `#FF5733` parse identically, though most brand guidelines pick a case convention and stick with it. The base-16 choice is convenient because one hex digit = nibble = 4 bits, two digits = byte = 0-255, so a single 2-digit pair maps cleanly to one 8-bit channel with no padding waste.

The conversion math goes both directions cleanly. **RGB to HEX**: for each channel, call `value.toString(16).padStart(2, '0')` to get the 2-digit hex pair (the `padStart` matters — without it, channel value 5 would serialize as `'5'` instead of `'05'`, producing invalid hex), then concatenate. For alpha-bearing RGB (`rgb(R G B / A)` or `rgba(R, G, B, A)`), multiply the 0-1 alpha float by 255, round to the nearest integer, hex-encode as a 4th pair, and emit the 8-digit form. **HEX to RGB** is the inverse: parse the 6-digit hex `#RRGGBB` as three 2-digit base-16 numbers via `parseInt(hex.slice(1, 3), 16)`, etc. Both directions are bit-exact: 16² = 256, exactly matching the 0-255 byte range each channel occupies, so an RGB → HEX → RGB round-trip produces the original integers verbatim with no float drift.

**Why HEX over RGB in CSS?** Three reasons. Hex is shorter — `#FF5733` is 7 characters versus `rgb(255, 87, 51)` at 16 characters, a meaningful difference when packed into a CSS custom property or a Tailwind config object. Hex has no whitespace bugs — CSS minifiers, JSON serializers, and command-line tools all handle a 7-character string cleanly without worrying about parenthesis matching or comma escaping. And hex is the format the entire design-tool ecosystem speaks natively — Figma's color panel, Sketch's swatches, Photoshop's color picker, every brand-guidelines PDF, every Dribbble shot's color callout — they all export hex by default. The copy-paste path from designer to developer is hex-shaped, which is why the RGB-to-HEX conversion is so frequent: developers receive RGB from a non-design tool (a canvas call, a screenshot eyedropper, a hardware sensor) and need to turn it into the hex form that the rest of their stack expects.

This tool's RGB → HEX workflow is one direction of a 5-spoke family that all share the same underlying unified color converter. The dedicated unified color converter is the hub — it shows all 9 formats simultaneously editable and is the right tool when your workflow needs more than just RGB and hex. The single-direction spokes target specific Google search intents: the reverse hex to RGB converter for the inverse direction (taking a hex from Figma and pulling out the 0-255 integers), the hex to HSL converter for the legacy designer-cognitive space, the hex to OKLCH converter for modern perceptually-uniform design systems (Tailwind v4 and shadcn both default to OKLCH now), and the hex to CMYK converter for print-prep approximations. All five spokes and the hub share the same parsing engine and the same conversion math, so the results are guaranteed identical across the family. Every conversion runs locally in your browser — your RGB values are never uploaded, never logged, and zero network requests fire as you type. Verify in DevTools.

// Serialize {r, g, b, alpha} → canonical hex string
// Emits 6-digit #RRGGBB when alpha === 1, 8-digit #RRGGBBAA otherwise.
function formatHex({ r, g, b, alpha = 1 }) {
  const pair = (v) => Math.round(v).toString(16).padStart(2, '0').toUpperCase();
  const rgb = pair(r) + pair(g) + pair(b);
  if (alpha >= 1) return `#${rgb}`;
  const a = pair(alpha * 255);
  return `#${rgb}${a}`;
}

console.log(formatHex({ r: 255, g: 87, b: 51 }));              // '#FF5733'
console.log(formatHex({ r: 59, g: 130, b: 246 }));             // '#3B82F6'
console.log(formatHex({ r: 255, g: 87, b: 51, alpha: 0.5 })); // '#FF573380'
console.log(formatHex({ r: 5, g: 0, b: 0 }));                  // '#050000' — padStart matters

Key Features

All RGB Input Shapes Parsed Identically

Modern space-separated `rgb(255 87 51)`, legacy comma-separated `rgb(255, 87, 51)`, percentage channels `rgb(100% 34% 20%)`, modern alpha via slash `rgb(255 87 51 / 0.5)`, and legacy `rgba(255, 87, 51, 0.5)` all parse identically. The parser normalizes every input shape to the same internal RGB tuple before hex serialization, so you can paste whichever form your source produces — Photoshop's integer triple, a stylesheet's `rgba()`, a Canvas API tuple — without manual reformatting.

Hex Output in Uppercase 6 or 8 Digit Form

The HEX field surfaces the value as `#FF5733` for opaque colors and `#FF573380` for alpha-bearing ones (8-digit form). Uppercase by default for consistency with most brand guidelines; one mechanical replace flips to lowercase if your style guide requires it. Both forms are valid CSS and ship in all evergreen browsers. The 8-digit alpha form shipped in all major browsers in 2018; for IE 11 fallback, the legacy `rgba()` form is still right there in the RGB field.

Bit-Exact, No Float Drift

RGB → HEX is integer-to-string math: `value.toString(16).padStart(2, '0')` produces the canonical 2-digit hex pair with zero float involvement. The reverse direction (`parseInt(pair, 16)`) is equally exact. A round-trip RGB → HEX → RGB → HEX produces the original input verbatim, indefinitely. The OKLCH internal source-of-truth means even the longer chain RGB → HSL → OKLAB → HEX stays bit-stable, which legacy converters routing through HSL don't guarantee.

Alpha Channel Encoded Cleanly

Alpha-bearing RGB (`rgb(255 87 51 / 0.5)` or `rgba(255, 87, 51, 0.5)`) emits the 8-digit hex form (`#FF573380`) automatically. The alpha float multiplies by 255 and rounds to the nearest integer before hex-encoding: `0.5 × 255 = 128 = 0x80`. The output drops back to 6-digit hex when alpha equals 1 to avoid leaking trailing `FF` pairs into stylesheets. Useful for design-token migration where alpha values in `rgba()` need to roundtrip into modern 8-digit hex form.

Eight Other Formats Visible Simultaneously

The same RGB you paste also drives HSL, HSV, HWB, OKLCH, OKLAB, CMYK, and the closest CSS named color — all visible at a glance on the same page. You're never locked into RGB → hex only. If a teammate needs the OKLCH triple for a Tailwind v4 token, the closest named color for documentation prose, or the CMYK approximation for a print quote, the values are already there with their own Copy buttons.

WCAG + APCA Contrast Built In

Pass an RGB tuple through and the contrast row immediately scores it against both white and black using WCAG 2.1 (regulatory floor: 4.5:1 for body text, 7:1 for AAA) and APCA Lc (proposed WCAG 3 successor: target `|Lc| ≥ 75` for body text). Useful when you've just converted an RGB tuple to hex and want to verify the resulting brand color is actually readable as a body-text color before shipping it.

Copy as CSS / Tailwind v4 / SwiftUI / Compose / Flutter

Below the picker, the Copy as code section turns the current color into ready-to-paste snippets for five platforms: CSS custom property (`--color-brand: #FF5733`), Tailwind v4 `@theme` token, SwiftUI `Color(red:green:blue:)` literal, Jetpack Compose `Color(0xFFFF5733)` constant, Flutter `Color(0xFFFF5733)`. The exact syntax each platform expects, ready to drop into an iOS asset catalog, Android theme file, or Flutter `ThemeData`.

100% In-Browser — No Upload, No Tracking

All RGB parsing, hex serialization, contrast scoring, and palette generation runs locally in your browser. Your RGB values are never transmitted, never logged on any server, never analyzed. Zero network requests as you type — verify in DevTools. Safe for unannounced brand palettes, internal design tokens, draft mockups under NDA, and any other confidential color work.

Shareable URL Hash for the Exact Color

The current color encodes into the URL hash as `#hex=ff5733` automatically on every change. Copy the URL, paste into a Slack thread or a GitHub issue, and anyone who opens it lands on the same RGB tuple with the same hex result. The hash lives only in your address bar and is never transmitted to the server (browsers don't include URL fragments in HTTP requests), so even sharing the link doesn't leak the color to any third party.

RGB to Hex Converter Alternatives

RapidTables RGB to Hex

browser tool

The default Google result for "rgb to hex" — a single-direction form with three RGB number boxes in, hex out, no other formats visible. Useful for one-off lookups when arriving from search. Lacks OKLCH, contrast checking, gamut detection, alpha handling, and the multi-format simultaneous view. This tool wins on every axis except the bare-bones single-conversion case.

ColorHexa

browser tool

Long-running per-color SEO pages with deep metadata: conversions, palettes, harmonies, gradients for any RGB you query. UI is dated (early-2010s), no OKLCH support, no APCA contrast, no wide-gamut handling. Strong for SEO discovery of a specific color via Google; weaker for active conversion workflows where typing into a unified-field UX is faster.

W3Schools RGB Calculator

browser tool

Beginner-friendly HEX/RGB/HSL toggle on a teaching-focused page, ubiquitous in search results. No OKLCH, no alpha handling beyond rgba, no advanced features. Useful as a reference next to W3Schools' explainer content. This tool wins on every other axis: more formats, perceptual math, gamut + contrast + CVD features, modern code export for Tailwind v4 / SwiftUI / Compose / Flutter.

Browser DevTools Color Picker

built-in browser feature

Chrome, Firefox, and Safari DevTools all ship a color picker that converts RGB to hex inline when you click a color swatch in the CSS pane. Free, no install, always available. Lacks OKLCH, lacks shareable URLs, lacks code-export for non-web platforms (SwiftUI, Compose). Reach for DevTools when you're already debugging CSS; reach for this tool when you need cross-platform output.

macOS Digital Color Meter

native macOS app

Bundled with every Mac since OS X — hover over any pixel and read the RGB / hex / linear values. Excellent for sampling pixel colors from any app on screen. Doesn't accept pasted RGB triples for conversion; it's a screen-sampler, not a converter. Use the EyeDropper button in this tool's picker (Chromium browsers only) for the same screen-sampling capability inside the browser.

ConvertingColors

browser tool

Per-color SEO pages covering many spaces (HEX, RGB, HSL, HSV, CMYK, XYZ, CIELAB). Lacks modern OKLCH support and the unified-field editing UX. Auto-generated content pages feel content-farm-ish but the conversion data is correct. Good for spelunking individual color metadata via Google; this tool is faster for active workflows.

RGB to Hex Examples

Input from CSS rgb() → hex for SwiftUI

rgb(255 87 51)

HEX output: `#FF5733`. The classic cross-platform workflow — a CSS stylesheet declares a brand color in modern `rgb()` syntax, the iOS team needs the hex to drop into a SwiftUI `Color(hex:)` extension or an asset catalog. Each channel converts independently: `255 → FF`, `87 → 57`, `51 → 33`, concatenated with a leading `#`. The same hex also pastes cleanly into Android Compose, Flutter, and Figma — hex remains the lingua franca for cross-platform color hand-off in 2026.

Designer's Photoshop RGB integers → CSS variable

rgb(59 130 246)

HEX output: `#3B82F6`. Adobe's Color picker reports RGB as three 0-255 integers (in Photoshop, Illustrator, and InDesign); the front-end team needs the hex to drop into a CSS custom property like `--color-brand: #3B82F6`. This particular triple is Tailwind's `blue-500` — `59 = 0x3B`, `130 = 0x82`, `246 = 0xF6`. Pasting it here once produces the matching hex plus the OKLCH triple for Tailwind v4 token migration, all in one step.

RGB with alpha → 8-digit hex

rgb(255 87 51 / 0.5)

HEX output: `#FF573380`. The alpha float multiplies by 255 (`0.5 × 255 = 127.5`, rounded to 128), then converts to a 2-digit hex pair (`128 = 0x80`) appended after the RGB hex. CSS 8-digit hex with alpha shipped natively in all evergreen browsers in 2018 (Chrome 62, Firefox 49, Safari 9.1, Edge 79). For pre-2018 browser support, the legacy `rgba(255, 87, 51, 0.5)` form is still available; the conversion is mechanical and preserves the same color exactly.

Percent RGB channels → hex

rgb(100% 50% 0%)

HEX output: `#FF8000`. CSS Color 4 allows percentage channels — each percentage maps to the 0-255 range with `value × 255 / 100`, then rounds to the nearest integer (`50% × 255 = 127.5 → 128 = 0x80`). Percent and integer forms are interchangeable and produce identical hex output. The percent syntax is sometimes preferred in hand-written stylesheets for readability when channel ratios matter more than raw integer values; the hex output normalizes both inputs to the same canonical 6-digit string.

Common RGB → Hex Conversions

Reference table of the 10 most-converted RGB tuples and their hex equivalents — pure primaries, pure secondaries, and two real-world brand colors from the Tailwind palette.

Black

rgb(0 0 0) #000000

Pure black. All three channels at zero — the absence of emitted light. Hex code (#000000).

rgb(0 0 0) #000000

Pure black on a screen is rarely the right design choice — try `#111` or OKLCH lightness 0.1-0.15 for softer body text.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

White

rgb(255 255 255) #FFFFFF

Pure white. All three channels at their maximum value (255). The brightest color in sRGB.

rgb(255 255 255) #FFFFFF

Pure white backgrounds can produce eye strain in dark environments — consider `#fafafa` or OKLCH 0.98 for warmer alternatives.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Red

rgb(255 0 0) #FF0000

Pure red. R channel at maximum, G and B at zero. The first of the three sRGB primaries.

rgb(255 0 0) #FF0000

Pure red is highly saturated and rarely fits a brand palette — most "red" brand colors sit closer to #DC2626 or #E53935.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Green

rgb(0 255 0) #00FF00

Pure green. G channel at maximum, R and B at zero. CSS named color `lime` (not `green`, which is #008000).

rgb(0 255 0) #00FF00

The CSS keyword `green` resolves to #008000 (half-bright), not #00FF00 — a frequent source of confusion. Use `lime` for pure RGB green.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Blue

rgb(0 0 255) #0000FF

Pure blue. B channel at maximum, R and G at zero. The third sRGB primary.

rgb(0 0 255) #0000FF

Pure blue on a white background fails WCAG AA contrast (3.7:1) — consider darker brand blues like #1D4ED8 (Tailwind blue-700) for body text.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Cyan

rgb(0 255 255) #00FFFF

Cyan — green and blue at maximum, red at zero. One of three sRGB secondaries. CSS named color `cyan` (or equivalently `aqua`).

rgb(0 255 255) #00FFFF

Cyan and aqua are exact synonyms in CSS — both resolve to #00FFFF. Pick one and stay consistent across your stylesheet.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Magenta

rgb(255 0 255) #FF00FF

Magenta — red and blue at maximum, green at zero. CSS named color `magenta` (or equivalently `fuchsia`).

rgb(255 0 255) #FF00FF

Magenta and fuchsia are exact synonyms in CSS — both resolve to #FF00FF. Common in test patterns and developer-tool overlays.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Yellow

rgb(255 255 0) #FFFF00

Yellow — red and green at maximum, blue at zero. The brightest of the three sRGB secondaries by perceived luminance.

rgb(255 255 0) #FFFF00

Yellow is the highest-luminance non-white color on screen — yellow text on white backgrounds is nearly invisible, even though hex looks fine on paper.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Tailwind blue-500

rgb(59 130 246) #3B82F6

Tailwind CSS's default blue-500 brand color — the canonical "web blue" of the mid-2020s. Used in countless dashboards, marketing sites, and admin tools.

rgb(59 130 246) #3B82F6

Tailwind v4 redefines blue-500 in OKLCH (`oklch(0.629 0.193 263.4)`) for perceptually-uniform ramps — the hex stays the same as a fallback.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

Tailwind rose-500

rgb(244 63 94) #F43F5E

Tailwind CSS's default rose-500 — a high-saturation pink-red used commonly for accent buttons, alert states, and brand contrast.

rgb(244 63 94) #F43F5E

Rose-500 passes WCAG AA (4.6:1) against white for large text but fails for body text — pair with rose-600 (#e11d48) or darker for body copy on white.

Need OKLCH instead? Try the dedicated hex to OKLCH converter for perceptually-uniform output.

How to Use the RGB to Hex Converter

  1. 1

    Type or paste an RGB tuple into the RGB field

    Drop any `rgb()` value into the RGB input — modern space-separated `rgb(255 87 51)`, legacy comma `rgb(255, 87, 51)`, with alpha via slash `rgb(255 87 51 / 0.5)` or via the `rgba(255, 87, 51, 0.5)` form, or percentage channels `rgb(100% 34% 20%)`. The tool normalizes all input shapes to the same internal RGB tuple before computing hex. Invalid characters, out-of-range integers, or malformed syntax produce a quiet inline error; valid RGB updates every other format field in real time.

  2. 2

    Read the hex code from the HEX field

    The HEX field above the RGB field shows the matching hex value: `#FF5733` for an opaque color, `#FF573380` for an alpha-bearing one (8-digit form). The output uses uppercase hex digits by default for consistency with most brand guidelines; lowercase (`#ff5733`) is one mechanical replace away and equally valid CSS. The conversion is bit-exact — a round-trip RGB → HEX → RGB recovers the original tuple verbatim with no float drift.

  3. 3

    Click Copy to grab the hex string

    Each format card has a Copy button on the right. One click and the value lands on your clipboard — the button label briefly flashes "Copied!" so you know. The copied string includes the leading `#` so it pastes directly into a CSS rule, a Figma color field, a SwiftUI hex extension, or an Android `colors.xml`. For platform-specific syntax (SwiftUI `Color(red:green:blue:)`, Compose `Color(0xFF...)`, Tailwind v4 `@theme` tokens), use the Copy as code section below the picker.

  4. 4

    Also visible: HSL, OKLCH, OKLAB, CMYK, named color

    The same RGB you paste lights up the other format fields too — HSL for legacy CSS, OKLCH and OKLAB for perceptually-uniform design systems, HSV and HWB for designer color-picker workflows, CMYK for print estimates, and the closest CSS named color for documentation and prose. You're never locked into RGB → hex only; if you also need the OKLCH triple for a Tailwind v4 `@theme` block, it's right there in the OKLCH field with its own Copy button.

  5. 5

    Use the picker for visual tweaks

    Below the format grid is an SL square + hue slider + alpha slider for visual exploration. Drag any control and every text field updates in real time, including the RGB and HEX you started with. On Chromium-based browsers (Chrome, Edge, Brave) the EyeDropper button activates the native `EyeDropper` API for sampling any pixel on screen, including outside the browser window — useful when you want to capture an RGB tuple from another app's UI without screenshotting first, then immediately read the hex.

Common RGB / Hex Mistakes

Forgetting padStart When Serializing RGB to Hex

Converting RGB to hex requires each channel's `toString(16)` to be left-padded to 2 digits. Without `padStart(2, '0')`, single-digit channel values produce invalid hex: `rgb(5, 87, 51)` would serialize as `#55733` (5 characters) instead of `#055733` (6 characters). Many ad-hoc converters skip the pad and produce broken output for any channel under 16. The standard idiom is `value.toString(16).padStart(2, '0')` for each of R, G, B, then concatenate and prepend `#`.

✗ Wrong
Skip padStart:
[5, 87, 51].map(v => v.toString(16)).join('') → '55733'
Produces invalid 5-character hex.
✓ Correct
Use padStart(2, '0'):
[5, 87, 51].map(v => v.toString(16).padStart(2, '0')).join('') → '055733'
Valid 6-character hex; works correctly for all channel values 0-255.

Forgetting to Round Float RGB Before Hex Encoding

When the RGB tuple comes from a normalized 0-1 float multiplied by 255 (common in OpenGL, SwiftUI, normalized image data), the result is often a float like `127.5` or `204.7`. Calling `toString(16)` on a float produces decimal hex like `'7f.8'` or `'cc.b333...'`, which is not valid CSS hex. Always `Math.round` (or `Math.floor`/`Math.ceil` per your rounding policy) the float to an integer before the `toString(16)` step.

✗ Wrong
Skip rounding:
(0.5 * 255).toString(16) → '7f.8'
Produces invalid hex with a decimal point.
✓ Correct
Round to integer first:
Math.round(0.5 * 255).toString(16).padStart(2, '0') → '80'
Valid 2-digit hex pair; matches CSS Color 4 normalization.

Confusing 8-Digit Hex Alpha Ordering

CSS 8-digit hex is `#RRGGBBAA` — alpha is the *trailing* pair. Some color libraries (notably older Android `Color.parseColor()`) use the opposite ordering `#AARRGGBB` with alpha as the *leading* pair, which is incompatible with CSS hex. An RGB value with 50% alpha serialized into CSS hex emits `#FF573380`; emitted into Android's leading-alpha format it would be `#80FF5733`. Always verify the target platform's alpha ordering before producing 8-digit hex.

✗ Wrong
Emit Android leading-alpha hex into CSS:
rgb(255 87 51 / 0.5) → #80FF5733 (Android format)
CSS parses as alpha=128, R=255, G=87, B=51 — wrong color entirely.
✓ Correct
Use the target platform's documented format:
for CSS: #FF573380 (alpha as last byte)
for Android Compose: Color(0x80FF5733) (alpha as first byte)
Don't cross-paste between the two without re-ordering.

Averaging RGB Channels Directly for Blending

RGB channels are gamma-encoded, not linear. Averaging two RGB values gives a perceptually-wrong midpoint. `(255, 0, 0)` averaged with `(0, 255, 0)` produces `(127, 127, 0)`, a muddy dark olive, not the bright yellow midpoint you'd expect from mixing red and green light. For correct blending, decode to linear-RGB first via the sRGB transfer function (CSS Color 4 §11.2), average in linear space, then re-encode. Or work in OKLAB / OKLCH where perceptual distance is uniform.

✗ Wrong
Average gamma-encoded RGB directly:
(rgb(255,0,0) + rgb(0,255,0)) / 2 = rgb(128, 128, 0)
Looks like dark olive, not bright yellow.
✓ Correct
Average in linear-RGB:
decode → linear-RGB → average → re-encode → rgb(188, 188, 0)
Visibly bright yellow, matching what physical light mixing produces.

Who Uses RGB to Hex

Frontend Devs Converting Canvas RGB to CSS Hex
Canvas API drawing functions report and accept colors as RGB tuples (`ctx.fillStyle = 'rgb(255 87 51)'`), but the surrounding CSS stylesheet wants hex variables (`--color-fill: #FF5733`). Pasting the RGB once produces the matching hex, ready to drop into a CSS custom property. Useful when extracting brand colors from a canvas-rendered chart or data visualization for reuse in static UI.
Designers Converting Photoshop RGB to Figma Hex
Adobe's Color picker (in Photoshop, Illustrator, and InDesign) reports RGB as three 0-255 integers across three channel boxes. Figma, by contrast, displays color values as hex by default in its design panels. Paste the three Photoshop integers as `rgb(...)` here, copy the hex output, drop into Figma's color field. Matches the original Photoshop color exactly without a screenshot-and-eyedropper detour.
Hardware Devs Converting LED Sensor RGB to Web Hex
Addressable LED strips, color sensors, and hardware RGB cameras all report channel values as 0-255 integers. When the readings need to drive a web dashboard ("the lamp is currently glowing this color"), the matching hex code is what the CSS `style="background: ..."` attribute expects. Paste the sensor's RGB triple, copy the hex, plug into the dashboard markup.
Game Devs Exporting Unity Color to Web Mockup
Unity's `Color` and Unreal's `FLinearColor` constructors take normalized 0-1 floats; multiplying each by 255 gives the matching RGB integers. Paste the resulting `rgb(...)` here, copy the hex, drop into the web mockup or marketing site that needs to match the in-game accent color exactly. The simultaneous OKLCH view also surfaces the perceptual lightness so the mockup palette can be hand-tuned to match the game's brightness levels.
Accessibility Engineers Auditing Photoshop Brand Colors
When the brand-style guide reports colors as RGB integer triples ("the brand orange is RGB 255 / 87 / 51") but the WCAG audit tool wants hex codes, this converter is the bridge. Paste the RGB triple, copy the hex, run through the audit. The WCAG and APCA contrast badges in this tool also surface the verdict in one step, so you don't need to bounce between three separate tools.
Email Devs Migrating rgba() to 8-Digit Hex
Modern email-client HTML supports 8-digit hex (`#FF573380`) for alpha-bearing colors, but legacy templates often store the same value as `rgba(255, 87, 51, 0.5)`. Pasting the rgba() here and reading the 8-digit hex output makes the migration mechanical. The HEX field shows `#FF573380` for the 50% alpha case; the legacy `rgba()` form remains in the RGB field for fallback contexts that still need it.
Developers Documenting Brand Tokens With Both Formats
Design-token documentation often shows the same color in both RGB and hex forms: hex for the CSS code block, RGB for the prose annotation ("the brand orange is `#FF5733`, equivalent to RGB 255 / 87 / 51"). Having both visible side-by-side lets a doc writer copy each in one pass instead of running two separate tools. The shareable URL hash also lets readers click through to the exact color under discussion.
QA Engineers Asserting Pixel Colors Against Hex Specs
Visual regression tests sometimes capture pixel colors as RGB integers (`expect(pixel).toMatchRgb([255, 87, 51])`), while the underlying spec is given in hex ("buttons must render as `#FF5733`"). Pasting the captured RGB here produces the matching hex, which the QA engineer can compare directly to the spec. The bit-exactness of the conversion means the comparison won't flake on float-drift differences.

RGB to Hex Math & Serialization

toString(16).padStart(2, '0') Is the One-Line Implementation
The entire RGB-to-hex conversion fits in one expression per channel: `value.toString(16).padStart(2, '0')`. JavaScript's `toString(16)` converts a decimal integer to its base-16 string representation. The `padStart(2, '0')` is the easy-to-forget detail — without it, channel value 5 would serialize as `'5'` instead of `'05'`, producing an invalid 5-character hex like `#55733` when joined with the other channels. The standard idiom is `[r, g, b].map(v => v.toString(16).padStart(2, '0')).join('')` followed by a `'#'` prefix.
Percentage Normalization: × 255 / 100, Then Round
CSS Color 4 allows percentage channels in `rgb()`: `rgb(100% 34% 20%)` is equivalent to `rgb(255 87 51)`. The normalization rule is `Math.round(percent × 255 / 100)`. `50% × 255 / 100 = 127.5` rounds to 128 (banker's rounding away from .5). The same rule applies to alpha when expressed as a percentage (`rgb(255 87 51 / 50%)` ↔ `rgb(255 87 51 / 0.5)`). Integer and percentage forms produce identical hex output after normalization; the tool surfaces the canonical integer form in the RGB field after re-normalizing.
Alpha to Hex: Multiply by 255, Round, Encode as Trailing Pair
Alpha-bearing RGB (`rgb(255 87 51 / 0.5)`) emits 8-digit hex by multiplying alpha by 255, rounding to the nearest integer, and encoding as a 4th hex pair appended after RGB. `0.5 × 255 = 127.5`, rounded to 128 = `0x80`, output `#FF573380`. The CSS Color 4 spec uses banker's-rounding (round-half-to-even) for this conversion, which the tool follows. The 8-digit form drops back to 6-digit when alpha is exactly 1 to avoid leaking trailing `FF` pairs into stylesheets.
RGB Input: CSS Color 4 Space-Separated and Legacy Comma Both Accepted
The parser accepts both the modern CSS Color 4 form `rgb(255 87 51)` and the legacy CSS 1 form `rgb(255, 87, 51)`. The modern form aligns with the other CSS Color 4 functional notations (`hsl()`, `lab()`, `oklch()`, `color()`) which all use space separation and slash-for-alpha. The legacy comma form is still supported in every evergreen browser and remains common in older codebases. Both produce identical hex output; the tool's hex serializer doesn't care which input shape arrived.
OKLCH Internal Source-of-Truth for Round-Trip Stability
Even though this spoke targets RGB → HEX specifically, the shared underlying converter holds the canonical color as an OKLCH triple internally. This means RGB → HEX → HSL → OKLAB → CMYK → RGB round-trips without per-step float drift; legacy converters that route through HSL or sRGB as their pivot accumulate rounding error at each conversion. The choice of OKLCH (over OKLAB) preserves Hue as a stable axis so dragging the hue slider doesn't accidentally cross-fade through gray. Per Björn Ottosson's 2020 OKLAB paper.
Channel Encoding: 8-Bit Unsigned, sRGB Gamma-Encoded
Each RGB channel is an 8-bit unsigned integer (0-255), encoded in the sRGB color space defined by IEC 61966-2-1 (1996). The values are *gamma-encoded* — meaning the relationship between channel value and perceived brightness is non-linear, following the piecewise sRGB transfer function (roughly a 2.4 exponent with a small linear segment near zero). This matters when you're doing color math: averaging two RGB values in their gamma-encoded form gives the wrong perceptual midpoint. For correct color blending, decode to linear-RGB first (CSS Color 4 §11.2), then average, then re-encode. The tool's OKLCH internal model makes this transparent.

Best Practices for RGB / Hex Workflows

Prefer Uppercase Hex in Brand Guidelines, Lowercase in Code
Brand guidelines, marketing PDFs, and designer-facing documentation typically use uppercase hex (`#FF5733`) for visual consistency — the all-caps look reads as a brand identifier. Code (CSS, JSON, JavaScript source) typically uses lowercase (`#ff5733`) by convention because lowercase is faster to type and more common in autogenerated linter output. Both are valid CSS and parse identically; pick one for each context and stay consistent. The tool emits uppercase by default; one mechanical replace flips to lowercase.
Emit 8-Digit Hex Only When Alpha < 1
When alpha equals 1 (fully opaque), drop back to the 6-digit form. A trailing `FF` pair (`#FF5733FF`) is legal CSS but visually clutters stylesheets and confuses some legacy parsers into mis-rendering. The 8-digit form should appear only when alpha is meaningfully transparent. This tool follows that rule automatically — opaque colors emit 6-digit hex, alpha-bearing colors emit 8-digit hex, and the cutoff is exact (alpha = 1.0 emits 6 digits; alpha = 0.9999 emits 8 digits to preserve the data).
Don't Average RGB Channels Directly for Color Math
RGB channels are gamma-encoded — averaging two RGB values gives the wrong perceptual midpoint. `(255, 0, 0)` averaged with `(0, 255, 0)` produces `(127, 127, 0)`, a muddy dark olive, not the visually-bright yellow midpoint you'd expect. For correct color blending, decode to linear-RGB first (CSS Color 4 §11.2), then average, then re-encode. Or, better, work in OKLAB or OKLCH where perceptual distance is uniform — that's exactly what design-system palette generators do.
Prefer Hex for CSS Variables, RGB for Hardware
When you're writing a CSS custom property or a Tailwind config token, prefer hex — it's terser and fits cleanly in JSON or YAML. When the consuming code does per-channel arithmetic (canvas calls, image manipulation, hardware LED drivers, OpenGL color attributes), the RGB integer form is faster to consume. The two formats describe the same color; the choice is purely about who's reading and writing, not about correctness. This tool's simultaneous-field view makes both equally cheap.
Validate Alpha Range Before Multiplying by 255
When implementing your own RGB → 8-digit-hex converter, validate that the alpha float falls inside `[0, 1]` before the `× 255` step. Out-of-range alpha (negative, or > 1) silently produces invalid hex pairs that some parsers accept and some reject — a fragile failure mode. Clamp first (`Math.max(0, Math.min(1, alpha))`), then multiply, then round, then hex-encode. The tool surfaces a quiet inline error for out-of-range alpha rather than emitting a broken hex string.
Use the URL Hash to Share Live Color Decisions
Every color change updates the URL hash as `#hex=ff5733` automatically. Copy the URL into a Slack thread or GitHub issue and anyone who opens it lands on the same color with the same hex. This is more reliable than pasting an RGB tuple in chat — recipients sometimes typo commas or drop a channel when manually entering the value — and lets a design-review thread reference an exact color rather than "the orange we discussed Tuesday." The hash is never transmitted to the server.

Frequently Asked Questions

How do you convert RGB to hex?
Convert each 0-255 channel integer to a 2-digit base-16 string, then concatenate with a leading `#`. In JavaScript: `[255, 87, 51].map(v => v.toString(16).padStart(2, '0')).join('')` returns `'ff5733'`. The `padStart(2, '0')` matters — without it, single-digit values like `5` serialize as `'5'` instead of `'05'`, producing an invalid hex. This tool runs the conversion live as you type — paste any `rgb()` value (with or without spaces, with comma or modern space syntax, with or without alpha) and the HEX field updates instantly with the matching `#RRGGBB` or 8-digit `#RRGGBBAA` value.
What is RGB in hex?
RGB in hex is the same color encoded as a 6-character base-16 string. Both forms describe a color as three channels (red, green, blue) on the 0-255 scale, anchored to the sRGB color space. `rgb(255 87 51)` and `#FF5733` are interchangeable anywhere a `` is accepted in CSS — they round-trip losslessly. Hex packs the same information into a terser form that fits cleanly in CSS variables and copies cleanly between Figma, Sketch, Photoshop, and code; `rgb()` keeps the channels addressable as separate integers for canvas calls and hardware APIs.
How do I get the hex code from RGB?
Take each channel value (0-255), call `toString(16)` to get its base-16 representation, left-pad with zero to 2 digits, and concatenate with a leading `#`. `rgb(255 87 51)` becomes: `255 → 'ff'`, `87 → '57'`, `51 → '33'`, result `#ff5733`. Capitalize if your style guide requires it (`#FF5733`); both forms are valid CSS. For alpha-bearing RGB like `rgb(255 87 51 / 0.5)`, multiply the alpha by 255, round, and append the resulting 2-digit hex pair: `0.5 × 255 = 128 = 0x80`, result `#ff573380`. This tool does both transforms automatically.
What is the formula for RGB to hex?
For each channel: `value.toString(16).padStart(2, '0')`. The `toString(16)` converts the integer to its base-16 representation; the `padStart(2, '0')` ensures the result is exactly 2 characters (necessary for values under 16, which would otherwise serialize as 1 character). Concatenate the three results, prepend `#`, and you have the canonical hex. Mathematically: for channel `n` in `[0, 255]`, the hex digits are `Math.floor(n / 16)` and `n % 16` mapped through `'0123456789abcdef'`. There is no rounding loss — 16² = 256, exactly matching the 0-255 byte range each channel occupies.
Does rgb(0,0,0) equal #000000?
Yes — exactly. `rgb(0, 0, 0)` and `rgb(0 0 0)` (modern space-separated CSS Color 4 syntax) both serialize to `#000000`, pure black with all three channels at zero. Every channel pair encodes as `00`, concatenated to a 6-character hex `000000`. The same equivalence holds at the other extreme: `rgb(255, 255, 255)` ↔ `#FFFFFF` (pure white). Any RGB triple has exactly one canonical 6-digit hex representation, and any 6-digit hex has exactly one RGB triple — the mapping is bijective across the full 16,777,216-color sRGB space.
Can RGB have an alpha channel?
Yes — use the `rgba()` legacy form `rgba(255, 87, 51, 0.5)` or the modern CSS Color 4 slash syntax `rgb(255 87 51 / 0.5)`. Both encode an alpha float from 0 (fully transparent) to 1 (fully opaque). When converting to hex, alpha becomes a 4th 2-digit pair appended after RGB: multiply by 255, round, hex-encode. `0.5 × 255 = 128 = 0x80`, so `rgb(255 87 51 / 0.5)` becomes `#FF573380`. 8-digit hex with alpha shipped in all evergreen browsers in 2018; before that, the `rgba()` form was the only way to express alpha in CSS.
How do hex and RGB differ?
They encode the same color in different notation. Hex packs three 0-255 channels into a 6-character base-16 string (`#FF5733`); `rgb()` spells the channels out in decimal (`rgb(255 87 51)`). Hex is shorter and design-tool-native — Figma, Sketch, Photoshop, and every brand guidelines PDF export hex by default, and most front-end developers can recognize `#3b82f6` as Tailwind blue-500 on sight. RGB is explicit channel-addressing, easier to compute against in JavaScript, and the only form that accepts percentage channels and natively-syntaxed alpha. Both are equally valid CSS and round-trip losslessly.
How accurate is RGB to hex?
Bit-exact. RGB → hex is integer-to-string math with zero float involvement: `toString(16).padStart(2, '0')` produces the canonical 2-digit hex pair for every value in 0-255, and the reverse (`parseInt(pair, 16)`) recovers the original integer exactly. A round-trip RGB → HEX → RGB → HEX produces the original tuple verbatim, indefinitely. 16² = 256, exactly matching the byte range, so there's no rounding loss in either direction. Percentage RGB inputs round to the nearest integer first (`50% × 255 / 100 = 127.5 → 128`), which is the standard CSS Color 4 normalization rule.

Related Tools

View all tools →