Colour Converter

Enter a colour – in any CSS notation – and read it off instantly in every other format: HEX, RGB, HSL, HWB, OKLCH, OKLab, Lab, LCH and CMYK. Plus a WCAG contrast check and a row of lightness steps. Everything runs locally in your browser.

Formats

HEX
CSS name
RGB
HSL
HWB
OKLCH
OKLab
LCH
Lab
CMYK

WCAG contrast

Aa
on white
Body textLarge text
Aa
on black
Body textLarge text
Aa
on your own colour
Body textLarge text

Lightness scale

Lightened and darkened in OKLCH, which keeps the hue intact. Click one to adopt it.

Everything runs locally in your browser – nothing is uploaded.

Which colour format for what?

FormatDescribesGood for
HEXRed, green, blue as hexadecimalThe most compact notation, understood everywhere
RGBRed, green, blue from 0 to 255Direct match to what the screen actually does
HSLHue, saturation, lightnessDeriving colour variants by hand
HWBHue, whiteness, blacknessTinting and shading with intuitive logic
OKLCHLightness, chroma, hue – perceptually uniformColour systems and scales that look even
Lab / LCHCIE colour space with the D50 white pointMeasuring colour distances, print preparation
CMYKCyan, magenta, yellow, blackA rough orientation for print

Why OKLCH is the most interesting column

HSL has a design flaw that gets in the way constantly: its “lightness” is purely arithmetic, not perceptual. hsl(60 100% 50%) (a bright yellow) andhsl(240 100% 50%) (a deep blue) share a lightness value of 50 %, yet they look nothing alike in brightness – the yellow glares, the blue is almost black. Build a palette in HSL with even lightness steps and you get a palette that is visibly uneven.

OKLCH (developed by Björn Ottosson in 2020, available in every current browser since CSS Color Level 4) fixes exactly that: its L corresponds to perceived lightness. Two colours at L = 60% genuinely look equally bright, whatever their hue. Just as important: changing lightness does not drag the hue along with it. That is what the scale above is built on – only the L is varied, so every step keeps the character of the original colour. The three values are lightness (0–100 %), chroma (0 to roughly 0.4) and hue angle (0–360°).

Reading WCAG contrast correctly

The contrast ratio ranges from 1:1 (two identical colours) to 21:1 (black on white). The Web Content Accessibility Guidelines require:

LevelBody textLarge text
AA (the usual legal baseline)4.5:13:1
AAA (enhanced)7:14.5:1

“Large text” means at least 18 pt (about 24 px), or 14 pt (about 18.7 px) when bold. WCAG 2.1 also requires 3:1 for user interface components and meaningful graphics. In the EU these values are binding for public sector bodies via the Web Accessibility Directive, and under the European Accessibility Act they have applied to many private providers since June 2025.

One point that is easy to miss: a semi-transparent colour has no contrast ratio of its own. What gets evaluated is always what ends up visible. This tool therefore composites the colour onto the respective background first and measures afterwards – move the opacity slider and you can watch the ratio move with it.

Which notations are accepted as input

Anything that would be valid in a stylesheet: #f0f, #663399,#66339980 (with alpha), rgb(102 51 153),rgba(102, 51, 153, .5), hsl(270 50% 40%), hwb(270 20% 40%),lab(32% 38 -48), oklch(44% 0.16 303), any of the 148 named CSS colours such as rebeccapurple or tomato – and even color-mix(). That is because the input is not read by a parser of our own but by the browser itself, which knows every notation it would accept in a stylesheet.

Frequently asked questions

Why does the CMYK value differ from the one in my graphics program?
Because a correct conversion to CMYK needs an ICC profile of the specific printing process – paper, ink and press all shape the result. The value shown here is the common arithmetic approximation without a profile: useful as a rough orientation, but not a binding value to hand to a print shop.

Why is the “CSS name” field usually empty?
Because there are only 148 named colours, and only exact matches appear there.#663399 is precisely rebeccapurple, whereas #663398 has no name at all.

Why do some OKLCH values look different after clicking a step of the scale?
Because not every combination of lightness and chroma can be shown in sRGB. A colour that is both very light and very saturated lies outside what an ordinary screen can display. Rather than clipping the channels – which would distort the hue – the chroma is reduced until the colour fits again.

Is anything I type uploaded?
No. The entire conversion is JavaScript running in your browser; there is no server that could receive anything. The only things remembered are the notation setting and the comparison colour for the contrast check.

Related: the data URL generator turns images and SVGs into Base64 data URLs for embedding straight into a stylesheet.