Color Converter and Contrast Checker

Convert between color notations, and measure the contrast ratio between a text color and its background. Conversion alone is only half of it — the question that actually blocks people is whether this text is legible on this background, and that is also the most common accessibility audit failure.

#ffffff
rgb(255 255 255)
hsl(0 0% 100%)
#1b41d8
rgb(27 65 216)
hsl(228 78% 48%)

Body text looks like this

And large text like this

7.52 : 1

  • Pass · AA body (4.5:1)
  • Pass · AA large (3:1)
  • Pass · AAA body (7:1)

Ratios follow WCAG. Large text means bold 18.66px or 24px and up. It is the most commonly failed accessibility check, so it is worth testing any grey text — the popular #777 lands at 4.48:1 on white, just under the line.

Notations accepted and not accepted

#abc and #aabbcc, rgb() and rgba() with commas or spaces, and hsl() and hsla() are all read. A fourth value (alpha) is parsed and then discarded — the contrast ratio is defined between two opaque colours, and the real contrast of translucent text is only known after it is blended with its background. Names like red and eight-digit hex are not accepted. A colour chosen with the picker lands in the same field.

How the ratio is computed

Each colour is reduced to its relative luminance: the sRGB values are linearised by undoing the gamma curve and weighted at 0.2126 for red, 0.7152 for green and 0.0722 for blue. Add 0.05 to both luminances and divide, and you have the ratio, which runs from 1:1 to 21:1. Green carries most of the weight, which is why yellow nearly disappears on white and blue looks dark on black. Swapping text and background gives the same number.

AA, AAA and large text

AA is 4.5:1 for body text and 3:1 for large text; AAA is 7:1 for body text. Large means at least 24px, or at least 18.66px when bold. The 3:1 figure is also the threshold for UI components such as icons and input borders (WCAG 1.4.11), so it serves that check as well. The preview draws both body-size and large text so that when the number is borderline you can judge by eye too.

Why HSL is shown alongside

A failing pair usually passes after a small shift in lightness. In hex it is hard to tell which digits to move and by how much; in HSL you keep the hue and lower the third value. That is why all three notations are shown together. HSL is rounded to whole numbers for display, so feeding it back in may move the RGB values by about one unit.

Values that cannot be read, and what the screen does

Names like red, four-digit #abcd, and RGB in percentages such as rgb(100% 0% 0%) cannot be read. Then a note appears under that field, the colour picker falls back to black, and the whole contrast panel disappears until both colours are readable again. Values beyond 0–255 are not rejected — they go straight into the arithmetic — so do not enter them.

The picker and the text field hold the same value

Pick a colour and a six-digit HEX lands in the field; type rgb() or hsl() and the picker shows that colour. But the picker only produces HEX, so the moment you nudge an HSL value with it, the notation switches to HEX. While the value is readable, all three notations are listed under the field, so take whichever you need from there.

Frequently asked questions

What are the thresholds?

Under WCAG, body text needs 4.5:1 and large text (bold 18.66px, or 24px and up) needs 3:1 to reach AA. The stricter AAA level asks for 7:1 on body text. The familiar gray #777 comes to 4.48:1 on white, which misses AA by a hair.

What is the lightest grey I can use on white?

For AA body text #767676 passes at 4.54:1 while the slightly lighter #777 fails at 4.48:1. For AAA, #595959 just clears it at 7.00:1. For the 3:1 of large text and icons, #949494 passes at 3.03:1. All of these sit right on the line, so one step darker is the safer choice.

Does anything I paste get sent to a server?

No. Everything runs inside your browser and nothing is uploaded or stored. That is why you can use it on things you would not normally paste into a web page, like an internal config file or a production query. It also works with your network disconnected.