DevKitHub

Programming

Color Converter — HEX, RGB, HSL and WCAG Contrast

Enter a colour in any CSS format to get every other format plus its contrast against white and black, calculated the way an accessibility audit calculates it.

Formats

HEX
#5b3df5
RGB
rgb(91, 61, 245)
HSL
hsl(250, 90.2%, 60%)
HSV
hsv(250, 75.1%, 96.1%)

WCAG contrast — relative luminance 0.1215

On white6.12:1AA text passAA large passAAA fail
On black3.43:1AA text failAA large passAAA fail
Readable texton this background
#ffffff

This tool runs entirely in your browser. Your input is never uploaded, stored or logged.

How it works

HEX, RGB, HSL and HSV are four ways of naming the same point, and converting between them is straightforward arithmetic. HSL and HSV differ more than their names suggest: for a fully saturated red, HSL lightness is 50% while HSV value is 100%, because HSL treats white and black as the two poles while HSV treats black as the floor and full colour as the ceiling. Picking the wrong one is why a colour ramp built in a design tool sometimes looks nothing like the one built in code.

The contrast figure is the part worth getting right, and it is not the difference between two brightness values. WCAG defines it as a ratio of relative luminances, where each channel is first taken back out of the sRGB gamma curve — displays encode values non-linearly, so averaging the encoded numbers measures the wrong thing — then weighted by how much that primary actually contributes to perceived brightness. Green carries 71% of it and blue barely 7%. A tool that averages the channels, or compares HSL lightness, produces a number that looks plausible and fails a real audit.

Two fixed points pin the formula: black on white is exactly 21:1, and any colour against itself is exactly 1:1. Both are asserted by tests here. The thresholds that matter are 4.5:1 for body text, 3:1 for large text at 18pt or 14pt bold, and 7:1 for the enhanced level. #999999 on white is a famous near-miss at 2.85:1 — it fails even the large-text threshold, which is why it turns up in so many audit reports.

Common problems

Every example below is run against this tool in our test suite, so what it says here is what the tool actually does.

That is not a colour this tool recognises.

nearly-blue
Why:
A name that is not one of the CSS colour keywords, or a format with a typo in it. CSS has a fixed list of names and nothing outside it is valid.
Fix:
Use a hex value like #5b3df5, a function like rgb(91 61 245) or hsl(250 91% 60%), or a real CSS colour name.

Converting to HSL and back gives a slightly different hex.

Why:
HSL is displayed with the hue as a whole number of degrees, and the mapping is not one-to-one at that precision. #5b3df5 is hue 249.78°, which rounds to 250° and returns as #5c3df5 — one unit of red different.
Fix:
Keep hex as the source of truth and treat the HSL value as a display of it. This is a property of rounded HSL, not of any one tool.

The palette passed a contrast checker but failed the accessibility audit.

Why:
Many checkers compare brightness or HSL lightness rather than WCAG relative luminance. The two agree for greys and diverge sharply for saturated colours, especially blues and yellows.
Fix:
Check the ratio against the published thresholds: 4.5:1 for body text, 3:1 for large text, 7:1 for enhanced. This tool uses the WCAG 2.1 formula.

Frequently asked questions

What is the difference between HSL and HSV?
Both use the same hue, but lightness and value measure different things. In HSL, 50% lightness is the full colour and 100% is white. In HSV, 100% value is the full colour and there is no white without dropping saturation. Pure red is hsl(0, 100%, 50%) and hsv(0, 100%, 100%).
How is the contrast ratio calculated?
By the WCAG 2.1 formula: each channel is converted out of the sRGB gamma curve, weighted 0.2126 red, 0.7152 green and 0.0722 blue to give relative luminance, then the two luminances are compared as (lighter + 0.05) / (darker + 0.05). The offset models ambient screen glare.
What contrast ratio do I need?
WCAG AA needs 4.5:1 for normal text and 3:1 for large text, which means 18pt or 14pt bold. AAA needs 7:1 and 4.5:1 respectively. User interface components and graphical objects need 3:1.
Does it support alpha?
Yes — eight-digit hex, rgba() and hsla() are all read, and the alpha value is shown. Note that contrast is computed on the colour itself; a semi-transparent colour composites against whatever is behind it, which changes the real ratio.

Read more about this

Last updated