How HEX, RGB and HSL color codes work, how to convert between them step by step, what alpha and 8-digit hex mean, and which WCAG contrast ratios text needs.
By Udit Agarwal · Updated October 18, 2026
A CSS color code writes one color as numbers, and HEX, RGB and HSL are three notations for the same colors. HEX and RGB give the amounts of red, green and blue light, so #3b82f6 and rgb(59, 130, 246) are exactly the same blue. HSL describes a color by its hue, saturation and lightness instead, and that blue is hsl(217, 91%, 60%) once rounded to whole numbers. Designers reach for HSL because it is easier to adjust by hand, while HEX is the compact form that most design tools and style guides use.
A screen builds every color from red, green and blue light. In the usual 8-bit color, each of the three channels has 256 levels, from 0 (off) to 255 (full), which gives 256 × 256 × 256 = 16,777,216 possible colors. All three at 0 is black, all three at 255 is white, and equal values in between are grays.
HEX and RGB write those three channel values directly, in base 16 and base 10. HSL is a different way of describing the same colors, and it converts to and from RGB with a fixed formula.
A hex code is a hash followed by three pairs of hexadecimal digits, #RRGGBB, one pair each for red, green and blue. Hexadecimal counts from 0 to 9 and then a to f, so a pair runs from 00 (0) to ff (255). Upper and lower case mean the same thing.
To read a pair, multiply the first digit by 16 and add the second. In #3b82f6, the red pair 3b is 3 × 16 + 11 = 59, green 82 is 8 × 16 + 2 = 130, and blue f6 is 15 × 16 + 6 = 246.
There is a shorter form and a longer one:
Alpha in hex is a fraction of 255. Fifty percent opacity is 0.5 × 255 = 127.5, which rounds to 128, or 80 in hex, so #00000080 is black at about 50% (strictly 50.2%). The 4- and 8-digit forms come from CSS Color Module Level 4 and work in all current browsers.
The rgb() function writes the same three channels in decimal: rgb(59, 130, 246). Each channel can also be a percentage of 255, so rgb(100%, 50%, 0%) is rgb(255, 128, 0), an orange.
Transparency is a fourth value from 0 (invisible) to 1 (solid). The older syntax is rgba(59, 130, 246, 0.5). Current CSS also accepts a space-separated form with a slash before the alpha, rgb(59 130 246 / 50%), and treats rgb() and rgba() as the same function, so either name accepts an alpha value. Both styles work in current browsers.
HSL stands for hue, saturation and lightness:
The appeal is that one number does one job. To make a darker or lighter version of a brand blue, keep the hue and saturation and move the lightness: hsl(217, 91%, 30%) is a deep navy-blue (#073c92), and hsl(217, 91%, 85%) is a pale blue (#b6d1fc). To find a contrasting accent, turn the hue halfway around the wheel: 217 + 180 = 397, which wraps to 37, and hsl(37, 91%, 60%) is the matching orange (#f6af3c).
HSL has one weakness. Its lightness is arithmetic, not perceptual. Pure yellow, hsl(60, 100%, 50%), and pure blue, hsl(240, 100%, 50%), both have 50% lightness, yet the yellow looks far brighter. Against white, the yellow has a contrast ratio of just 1.07:1 and the blue 8.59:1. So never assume two HSL colors with the same lightness will be equally readable.
Take #3b82f6 all the way through.
HEX to RGB. Convert each pair from base 16, as above: 3b = 59, 82 = 130, f6 = 246. The result is rgb(59, 130, 246).
RGB to HSL. Divide each channel by 255 to get values between 0 and 1: R = 0.2314, G = 0.5098, B = 0.9647. Then:
The answer is hsl(217, 91%, 60%). Now convert it back and you get #3c83f6, one step away from where you started in both red and green, because the HSL values were rounded to whole numbers. Keep the HEX or RGB value as your source of truth and treat a rounded HSL value as a convenient way to adjust it.
CSS also recognizes 148 color names, from aliceblue to yellowgreen. Some are handy shortcuts, such as teal (#008080), and one, rebeccapurple (#663399), was added in memory of a web developer's daughter.
CSS Color Module Level 4 adds notations that go beyond RGB: hwb(), lab(), lch(), oklab() and oklch(). The one worth knowing is OKLCH, which describes a color by lightness, chroma (colorfulness) and hue, and is built so that equal steps of lightness look roughly equal to the eye. That fixes the HSL problem above and makes OKLCH a good fit for shade scales. The same blue is oklch(0.6231 0.188 259.81). Current browsers support all of these notations, and the Color Format Converter shows a color in each of them at once.
Color is also a readability question. The Web Content Accessibility Guidelines (WCAG 2) measure the contrast ratio between text and its background as (L1 + 0.05) / (L2 + 0.05), where L1 and L2 are the relative luminance of the lighter and darker color. The ratio runs from 1:1 (identical colors) to 21:1 (black on white).
| Level | Normal text | Large text |
|---|---|---|
| AA (the usual target) | 4.5:1 | 3:1 |
| AAA (enhanced) | 7:1 | 4.5:1 |
WCAG counts text as large from 18 point, or 14 point bold, which is roughly 24 CSS pixels, or about 18.5 pixels bold. Interface parts such as input borders, and graphics needed to understand the content, need at least 3:1. The ratio is not rounded, so 4.499:1 fails AA.
Some real pairs show how quickly a color can fall short. White text on #3b82f6 measures 3.68:1, which passes for large headings but fails for body text, while black text on the same blue reaches 5.71:1. On a white page, #767676 is the lightest gray that passes AA at 4.54:1; one step lighter, #777777 drops to 4.48:1. Check any pair in the Contrast Checker, and preview how a design reads with color vision deficiency in the Color Blindness Simulator.
The CSS Color Converter reads one color and shows it as HEX, RGB and HSL together, next to a live swatch. It accepts hex codes of 3, 4, 6 or 8 digits, rgb() and rgba() with commas or spaces, channels as numbers or percentages, hsl() and hsla(), and a short list of common names such as navy, teal, gold and indigo, plus transparent. Alpha carries through to all three outputs as an 8-digit hex code, rgba() and hsla(). HSL is rounded to whole numbers, as in the example above. It does not read lab(), lch(), oklch() or less common names such as rebeccapurple or salmon; the Color Format Converter handles those. Conversion happens in your browser, and the values you type are not uploaded.
What is the difference between HEX and RGB? None in the color itself. Both give the red, green and blue channel values, HEX in base 16 and RGB in base 10, so #ff8000 and rgb(255, 128, 0) are the same orange.
How do I convert a HEX code to RGB? Split the code into three pairs and convert each from base 16: multiply the first digit by 16 and add the second, counting a to f as 10 to 15. For #3b82f6 that gives 59, 130 and 246, so rgb(59, 130, 246).
What does an 8-digit hex code mean? The last two digits are the alpha channel, from 00 (transparent) to ff (opaque). #3b82f680 is the blue #3b82f6 at about 50% opacity, the same as rgba(59, 130, 246, 0.5).
What is HSL used for? Adjusting colors by hand. Changing only the lightness gives tints and shades of the same hue, and rotating the hue by 180 degrees gives the complementary color. It is less reliable for judging readability, because equal HSL lightness does not mean equal brightness to the eye.
What contrast ratio does text need? WCAG 2 level AA asks for at least 4.5:1 for normal text and 3:1 for large text, meaning 18 point or 14 point bold. Level AAA raises those to 7:1 and 4.5:1.
Is rgba() deprecated? No. Current CSS treats rgba() as another name for rgb(), and both accept an alpha value, so rgb(0 0 0 / 50%) and rgba(0, 0, 0, 0.5) give the same result. Either is fine in a stylesheet.
Why does converting HSL back to HEX give a slightly different color? HSL values are usually rounded to whole numbers, and that rounding loses a little precision. hsl(217, 91%, 60%) comes back as #3c83f6 rather than the original #3b82f6, a difference the eye cannot see but a design token check can.
All Code Formatters tools · All guides