Conversion calculator

Colour Converter

Hex, RGB and HSL — and whether text on it will actually be readable.

Calculator

Hex with or without the hash, three or six digits, or an rgb() value.

Swatch

Relative luminance 0.107 — not the same as the RGB average.

Try:

The same colour in every format

hex#1d4ed8
rgbrgb(29, 78, 216)
hslhsl(224.3, 76.3%, 48%)

Contrast, which is usually the real question

On white6.7:1Passes AA for body text, but not AAA.

On black3.13:1Passes AA for large text only — 18pt, or 14pt bold.

WCAG asks for 4.5:1 for body text and 3:1 for large text. The threshold is sharper than it looks — #767676 passes on white and #777777 fails, one hex digit apart.

What this converter covers

The format change, plus the WCAG contrast ratio on white and black — because that is usually why the code was being looked up.

  • Hex, RGB and HSL in both directions
  • Three-digit shorthand expanded correctly, by doubling rather than padding
  • The WCAG contrast ratio against white and black, with a plain verdict
  • Relative luminance, which is not the average of the channels
  • A note when the colour is a grey and therefore has no hue at all
Contrast checked WCAG luminance curve Hex, RGB, HSL Both directions

Free, no signup — exact by definition, not an estimate.

Updated 7 September 2026

At a glance

Formula shown
Contrast = (L₁ + 0.05) ⁄ (L₂ + 0.05), where L is WCAG relative luminance
Scenario support
#f0a = #ff00aa · #767676 on white = 4.54:1 (passes) · #777777 = 4.48:1 (fails)
Educational estimate
Planning support from the values you enter — not professional advice.

Shorthand doubles, it does not pad

Three-digit hex is shorthand for six, and the expansion is by duplication: each digit is repeated, so #f0a becomes #ff00aa.

The plausible wrong answer is zero-padding, which would give #f00a00 — a dark red instead of a bright pink, and a completely different colour. It is an easy thing to implement wrongly and an easy thing to assume wrongly when reading a stylesheet quickly.

The reason for duplication rather than padding is that it keeps the shorthand spread across the full channel range. #fff has to be white, so f must become ff rather than f0; and #000 has to be black. Duplication is the only expansion that puts the endpoints where they belong.

This tool expands shorthand and says so, rather than doing it silently — because when a colour looks wrong on screen, knowing which expansion was applied is the first thing worth checking.

One hex digit, two sides of AA

Most people looking up a hex code are about to put text on it or next to it, so the conversion is rarely the real question — readability is. WCAG sets that as a contrast ratio: 4.5:1 for body text, and 3:1 for large text, meaning 18pt or 14pt bold.

The threshold is sharper than it looks. On a white background, #767676 passes at 4.54:1 and #777777 fails at 4.48:1. One hex digit — a change invisible on screen — moves a colour from compliant to non-compliant.

That sharpness is why guessing is a poor strategy. A grey that looks “dark enough” in a mockup can sit either side of the line, and the only way to know is to compute it. The tool does that against both white and black, since a colour that fails on one often passes comfortably on the other.

Two things the ratio does not cover, and both matter. It is a floor rather than a target: a thin 300-weight font at 14px passing at exactly 4.5:1 is still hard to read, and the standard does not model weight at all. And it treats every colour pair alike, so it does not flag combinations that are specifically difficult for colour-blind readers — red on green can pass and still be unusable for roughly one man in twelve.

Why RGB maths is not brightness maths

#808080 is RGB 128, the exact midpoint of the 0–255 byte range. Its relative luminance is about 0.216 — nowhere near half. Mid-grey is much darker than halfway between black and white to the eye, and to any correct measurement.

The reason is the sRGB transfer curve. Channel values are not linear in light output: they are encoded with a gamma curve that allocates more precision to dark tones, because human vision is more sensitive there. Undoing that curve is the first step in the luminance formula, and it is why the formula looks so unlike an average.

The channels are also weighted very unequally — roughly 21% red, 72% green, 7% blue — because the eye is far more sensitive to green than to blue. Pure green is more than eight times brighter than pure blue at full intensity, despite both being ff in their own channel.

The practical consequence: “20% darker” done by scaling RGB channels is not 20% darker. Multiplying every channel by 0.8 produces something the eye reads as considerably more than a fifth darker, and the mismatch is worst in the mid-tones where most interface design happens. That is why HSL lightness and perceptual spaces exist, and why a palette generated by naive channel arithmetic tends to look uneven.

Greys have no hue

When the three channels are equal — #000000, #808080, #ffffff — the colour has zero saturation, and hue has nothing to describe. There is no direction on the colour wheel to point at.

Every implementation reports hue 0 for these, and that is a convention rather than a measurement. It falls out of the arithmetic: the formula picks a branch based on which channel is largest, and when all three are equal the difference is zero and the branch is arbitrary. Reporting zero is tidy and means nothing.

This matters when generating palettes programmatically. Taking a grey, adjusting its “hue”, and converting back does nothing at all while saturation stays at zero — the hue is carried but has no effect. A grey has to gain saturation before a hue is meaningful, which is a different operation from shifting one.

The tool says so when the colour is achromatic, rather than presenting the zero as though it were information.

Doing it in a spreadsheet

Hex to RGB is three HEX2DEC calls on two-character slices: =HEX2DEC(MID(A1,2,2)) for red, with MID(A1,4,2) and MID(A1,6,2) for green and blue, assuming the hash is in position one. Going back is =DEC2HEX(R,2)&DEC2HEX(G,2)&DEC2HEX(B,2), and the second argument is what forces the leading zero on single-digit channels.

For contrast, build the luminance curve in its own column rather than inline, because it is piecewise: =IF(c<=0.03928, c/12.92, ((c+0.055)/1.055)^2.4) per channel with c being the channel divided by 255, then weight them 0.2126, 0.7152 and 0.0722 and sum. The ratio is =(L1+0.05)/(L2+0.05) with the lighter colour on top.

Writing it out that way is worth the extra cells. A single collapsed formula hides the gamma step, and the gamma step is exactly the part that people leave out when they reimplement this from memory — producing a ratio that looks reasonable and passes colours that should fail.

Related calculators

Other notations worth converting:

Numeral BaseBinary, octal, decimal and hex — showing the 4-bit grouping that makes hex work, and handling negatives at a width you choose.
Data StorageBytes, KB, MB, GB and TB alongside the binary KiB, MiB, GiB and TiB — and why a 1 TB drive shows as 931 GB.
AngleDegrees, radians, gradians, arcminutes and arcseconds — and why a spreadsheet’s SIN(90) returns 0.894 rather than 1.
PercentageSolve X% of Y, what percent X is of Y, reverse percentage, increase/decrease, discounts, and tax, tip, or commission.
Roman NumeralsNumbers to Roman numerals and back, 1 to 3,999 — reading the older spellings like IIII and writing the standard modern form.
Million, Billion and TrillionThousand to trillion in both naming conventions, since a billion is 10⁹ in the US and 10¹² across much of Europe.

More in Conversion, or browse all calculators.

Sources and methodology

Nothing here is fetched and there is no data feed. The format conversions are exact by construction; the contrast figures are not a convention of this site but come from the WCAG relative-luminance formula, including the sRGB transfer curve that makes channel values non-linear in perceived brightness. The three-digit expansion rule comes from the CSS colour specification.

Conversion note

The format conversions here are exact, and the contrast figures follow the WCAG formula precisely. What a ratio cannot tell you is whether a design is actually readable. WCAG contrast is a threshold rather than a target, and passing it is a floor rather than a guarantee — thin or very light font weights, small sizes, text over photographs, and low-quality screens all reduce real legibility at the same measured ratio. The formula also treats all colour pairs alike, so it does not detect the combinations that are difficult for colour-blind readers specifically; red against green can pass comfortably and still be unusable for roughly one man in twelve. Colour management is a further layer this page does not model: sRGB is assumed throughout, and a wide-gamut display or an untagged image will render the same hex code differently. For anything being audited for accessibility, test the rendered page rather than the swatch.

How we calculate · Found an error? email us

Authorship & verification

Written and maintained by , a business operator who builds spreadsheet-based calculators.

What's changed (4 updates)

Published 7 September 2026

  1. Published the Colour Converter: hex, RGB and HSL in both directions, plus the WCAG contrast ratio against white and black — because someone looking up a hex code is usually about to put text on it.
  2. The contrast threshold is sharper than it looks and the page shows it: #767676 passes AA on white at 4.54:1 and #777777 fails at 4.48:1, one hex digit apart. Both sides of that boundary are asserted, since an error in the luminance curve would move it without breaking anything else.
  3. Three-digit shorthand expands by DOUBLING each digit — #f0a is #ff00aa, not the #f00a00 that zero-padding would give — and the expansion is annotated rather than done silently.
  4. Also states two things a converter usually omits: RGB 128 is the byte midpoint but has a relative luminance near 0.216, so channel arithmetic is not brightness arithmetic; and greys have no hue at all, so the 0 every implementation reports is a convention rather than a measurement.

Add this calculator to your site

Responsive embed — and private: nothing your visitors type leaves their browser.