Skip to main content
Redmoon Converters
🎨 Design & Creative

Color Converter — HEX, RGB, HSL, OKLCH & Contrast

Convert any color between HEX, RGB, HSL, HWB, OKLCH and LCH. Includes WCAG 2.2 contrast checker against any background or alternate foreground.

Built and maintained by Paul Clark, Redmoon Software · Checked against what this tool computes on

Accepts hex, rgb, hsl, hwb, oklch, lch and CSS names.
FormatValue

WCAG contrast checker

Contrast ratio
Body text 16 px
Large text 24 px
Quick reference

sRGB → linear via the standard gamma curve, then to OKLab using Björn Ottosson's matrix, then to OKLCH by polar coords. HSL/HWB use the standard CSS Color Module 4 formulas.

WCAG 2.2 contrast: ratio = (L1 + 0.05) / (L2 + 0.05) using relative luminance from the sRGB→linear weighted sum (0.2126 R + 0.7152 G + 0.0722 B). AA = 4.5, AAA = 7 for normal text; 3 and 4.5 for large (18 pt / 14 pt bold).

How it works

Type any colour and it is parsed to sRGB, then re-expressed six ways: HEX, RGB, HSL, HWB, OKLCH and LCH. Conversions follow the standard path. sRGB is linearised with the usual gamma curve, dividing values at or below 0.04045 by 12.92 and otherwise raising (v + 0.055) ÷ 1.055 to the power 2.4. From there it goes through Björn Ottosson's OKLab matrices for OKLCH, or through XYZ and CIE Lab with a D65 white point for LCH.

The input field accepts more than the label suggests: hex in 3, 4, 6 or 8 digits, rgb() and rgba(), hsl() and hsla(), hwb(), oklch(), lch(), and seventeen basic CSS colour names such as teal, olive and magenta. Separate Foreground and Background fields drive the WCAG contrast panel, which defaults to #FFFFFF on #F42C2C. That panel reports the ratio and pass/fail chips for AA normal (4.5), AA large (3), AAA normal (7) and AAA large (4.5).

Alpha is parsed but then discarded, so an 8-digit hex or an rgba() with transparency converts as though fully opaque, and contrast is always computed on opaque colours. Out-of-gamut OKLCH and LCH inputs are clipped channel by channel back into sRGB rather than properly gamut-mapped, which can shift hue on very saturated values. The contrast maths is WCAG 2.x relative luminance, not the newer APCA model, and it grades colour pairs rather than real rendered text.

Frequently asked questions

What is OKLCH and why use it instead of HSL?

OKLCH is a perceptually uniform polar space, meaning equal changes in its lightness value look equally different to the eye, which HSL does not guarantee. That makes it far better for generating tints and shades of a brand colour without lightness drifting between hues.

Does white text pass contrast on a red background?

With the defaults of #FFFFFF on #F42C2C the ratio comes out around 4.00:1. That clears AA large text at 3:1 but falls short of AA normal at 4.5:1 and both AAA thresholds, so reserve it for headings at 24 px or larger rather than body copy.

Can I paste a colour that has transparency?

You can paste 8-digit hex or rgba() and it will parse, but the alpha channel is dropped. Every output format and the contrast ratio treat the colour as fully opaque, so for a semi-transparent overlay you need to work out the composited colour first.

Which named colours does the input recognise?

Seventeen of them: black, white, red, lime, blue, yellow, cyan, magenta, silver, gray, olive, green, purple, teal, navy, maroon and orange. Anything outside that list, such as rebeccapurple or coral, is rejected as an invalid colour, so paste the hex value instead.

What is the difference between the LCH and OKLCH rows?

Both are polar lightness, chroma and hue forms, but LCH is built on CIE Lab with a D65 white point while OKLCH uses OKLab. OKLab was fitted specifically to fix Lab's hue shifts in blues and purples, so OKLCH hue stays truer as you change lightness.

The same numbers mean different colours

A colour space defines what a set of numbers actually refers to. The same RGB triplet is a different physical colour in sRGB, Display P3 and Adobe RGB, because each defines different primaries and a different white point. Converting between them is not a relabelling — it is a change of the numbers to preserve the appearance.

sRGB remains the safe default for anything heading to the web, because it is what browsers assume when no profile is present.

Gamut, and why conversion loses information

Conversion between spaces is lossy at the edges. A colour inside a wide gamut like Adobe RGB may have no equivalent in sRGB, and it must be mapped to something inside — which is why saturated colours can flatten noticeably when a wide-gamut image is converted for the web.

CMYK is a further step again, because it is subtractive and device-dependent: the same file printed on different presses with different inks and papers produces different colour, which is what proofing exists to control.

The practical rule is to work in the widest space your workflow supports and convert once, at export, to the space the output needs — rather than converting back and forth, which compounds the loss each time.

Where these numbers come from

The standard or formula behind this tool, so you can check it rather than take it on trust.

  • IEC 61966-2-1 — sRGB colour space

    The default colour space assumed for web values. Conversions between spaces are lossy at the gamut edges, so a round trip does not always return the value you started with.

Related tools