HandyTools Hub

← All guides

HEX, RGB, and HSL Color Formats Explained: How to Convert and When to Use Which

2026-08-11

Every web developer juggles three ways to write the same color: a designer hands you #FF5733, a CSS framework uses rgb(255, 87, 51), and a design tutorial insists HSL is the only sane choice. They’re three notations for the same underlying thing, but they are not equally good at every task — and converting between them by hand is error-prone enough that everyone eventually reaches for a tool. This guide explains what each format actually encodes, how the conversions work, and the practical rule for which one to use where.

RGB: Three Channels of Light

A screen pixel is three tiny lights — red, green, blue — and RGB notation states how bright each one shines, on a scale of 0 to 255. rgb(255, 87, 51) means full red, a third of the green, a fifth of the blue. All zeros is black, all 255s is white, and equal values in between give grays.

Why 0–255? Each channel is one byte: 8 bits, 2⁸ = 256 levels. Three channels × 8 bits is the “24-bit color” of classic display specs, good for about 16.7 million distinct colors. The 255 ceiling also explains the most common RGB mistake: values are absolute intensities, not percentages. rgb(128, 128, 128) is mid-gray, not “half red, half green, half blue.”

Modern CSS also accepts rgb(255 87 51) (space-separated, no commas) and a fourth alpha channel for opacity: rgb(255 87 51 / 0.5) or the older rgba(255, 87, 51, 0.5).

HEX: RGB in a Trench Coat

#FF5733 is not a different color model — it’s the same three channels written in hexadecimal: FF = 255, 57 = 87, 33 = 51. Red, green, blue, two hex digits each, prefixed with #. Since hex is base 16, one byte is always exactly two digits (00FF), which makes the string compact and fixed-width — the reason it became the default format in design tools and CSS shorthand.

Reading HEX fluently takes one skill: knowing that the size of each pair is what matters, not the exact value. #F… means “lots of this channel,” #3… means “a little.” So #FF5733 reads instantly as “mostly red, some green, barely blue” = orange-ish. Shorthand like #F00 expands each digit (#FF0000, pure red), and an eight-digit form appends alpha: #FF573380 is 50% opacity (80 hex = 128 decimal ≈ half of 255).

Converting RGB → HEX by hand: divide each channel by 16; quotient and remainder are your two digits (with 10–15 written A–F). 87 ÷ 16 = 5 remainder 7, so 57. Converting back: first digit × 16 + second digit. If that’s not how you want to spend your afternoon, the Color Picker shows HEX, RGB, and HSL values live as you adjust any one of them.

HSL: The Format Designed for Humans

RGB describes colors the way hardware produces them; HSL describes them the way people think about them:

  • Hue (0–360°): position on the color wheel. 0° is red, 120° is green, 240° is blue; everything else is an interpolation around the circle.
  • Saturation (0–100%): how vivid the color is. 0% is a pure gray regardless of hue; 100% is full intensity.
  • Lightness (0–100%): how close to black or white. 0% is always black, 100% is always white, 50% is the “pure” color.

The killer feature is that each dial does one intuitive thing. Want a darker version of your brand color? Drop lightness from 50% to 35% — done, no math. Want it muted? Lower saturation. Want the complementary accent? Add 180° to the hue. Try any of those in RGB and you’re guessing at three entangled numbers: darkening rgb(255, 87, 51) correctly means scaling all three channels proportionally, and your first attempt usually shifts the hue.

This is why HSL shines for systematic design: hover states (lightness −10%), disabled states (saturation −40%), generating a whole palette from one brand hue. The Color Palette Generator exploits exactly this — it varies saturation and lightness around a base hue to produce families of colors that harmonize automatically, something that’s nearly impossible to eyeball in HEX.

Converting HSL ↔ RGB: The Shape of the Problem

HSL → RGB is more involved than HEX conversion because the hue angle first picks a sector of the color wheel (which two channels are active), and saturation/lightness then scale the result. The rough algorithm: compute chroma (colorfulness) from saturation and lightness, find which 60° sector the hue falls in, assign chroma to the appropriate channels, then shift everything up by the lightness offset. It works, but it’s the kind of formula nobody should re-derive per task — this is what color tools are for.

The conversions worth internalizing are the anchors: hsl(0, 100%, 50%) = #FF0000 (red), hsl(120, 100%, 50%) = #00FF00 (green), hsl(240, 100%, 50%) = #0000FF (blue), and any color at 0% saturation is a gray whose level comes from lightness alone.

Which Format When

  • HEX: the default for constants — brand colors, design tokens, anything copy-pasted from a design tool. Compact, universally supported, greppable.
  • RGB/RGBA: when you’re already working with channels — canvas pixels, image processing, or when you need quick alpha on an existing RGB value.
  • HSL: for anything computed or systematic — theme variants, hover/active states, programmatic palettes, dark-mode adaptations (drop lightness across the board and you have a first draft of a dark theme).

A practical CSS pattern combines them: define brand colors as HEX custom properties, then derive variants with hsl() using color-mix() or by storing the channels separately. And whatever format the final CSS uses, name your tokens semantically (--color-danger, not --color-red) so the underlying value can change without a codebase-wide hunt. If a stakeholder sends you a color by name — “make it coral” — the Color Name Finder maps names to their exact HEX/RGB values and back, which beats guessing whether they meant #FF7F50.

Quick Reference

  • HEX = RGB in hexadecimal: #FF5733rgb(255, 87, 51). Same model, different notation.
  • RGB channels are 0–255 absolute intensities; equal values are grays.
  • HSL: hue = which color (0–360°), saturation = how vivid, lightness = dark ↔ light (50% is pure).
  • Darken/lighten and desaturate in HSL; store constants in HEX; use RGBA/HSLA when you need opacity.
  • #RGB shorthand doubles each digit; #RRGGBBAA appends alpha as two more hex digits.