Colour Converter
HEX, RGB, HSL and OKLCH, with a contrast check and a ramp that holds its hue.
- HEX
#3b82f6 - RGB
rgb(59, 130, 246) - HSL
hsl(217, 91%, 60%) - OKLCH
oklch(62.3% 0.188 259.8)
Contrast
- FailAA normalneeds 4.5:1
- PassAA largeneeds 3:1
- FailAAA normalneeds 7:1
- FailAAA largeneeds 4.5:1
Computed on linear light rather than raw channel values, which is what makes the figure match WCAG rather than flattering mid-tones. “Large” means 18pt, or 14pt bold, roughly 24px and 19px bold on the web.
Tints and shades
Built by holding hue and chroma and walking lightness in OKLCH, not by mixing toward white. Mixing is what sends a saturated blue through a washed-out lilac on its way up.
OKLCH is worth the extra line in your stylesheet. HSL callshsl(60 100% 50%) andhsl(240 100% 50%)equally light; one is a bright yellow and the other a dark blue. In OKLCH the same two are 97% and 45%, which is why equal steps in OKLCH look equal and equal steps in HSL do not.
Every value here is computed through linear light and the sRGB transfer function, so a hex code round-trips through OKLCH and back to the same byte.
How the Colour Converter works
Paste a colour in any format and get it back in all of them, including OKLCH, which is in CSS Color 4 and is the one worth having. Underneath it, a WCAG contrast check against any second colour, and an eleven-step tint and shade ramp built by walking lightness in OKLCH rather than mixing toward white, so the colour stays recognisably itself the whole way up.
Also known as: hex to rgb · hex to hsl converter · oklch color converter · colour contrast checker · rgb to hex online
Why HSL cannot be trusted with lightness
HSL was designed in the 1970s to be easy to compute, and easy to compute is exactly what it is. Its lightness is the midpoint between the largest and smallest RGB channel, which is arithmetic on numbers rather than a statement about how bright something looks. The consequence is that hsl(60 100% 50%) and hsl(240 100% 50%) both claim fifty percent lightness while one is a bright yellow you can barely read black text on and the other is a dark blue you can barely read black text on for the opposite reason.
That is not a curiosity, it is the reason palettes built by walking HSL lightness come out uneven. A design system with steps at 90, 80, 70 and so on down looks smooth in the yellows and lurches in the blues, and no amount of eyeballing fixes it because the space itself is lying about the quantity you are stepping through.
OKLCH, published by Björn Ottosson in 2020 and now part of CSS Color 4, is built the other way round: it starts from measurements of how human vision responds and arranges the space so equal numerical steps look like equal perceptual steps. The same yellow and blue come out at 97% and 45%. Step lightness in OKLCH and the steps look even, because they are.
Gamma, and the mistake it causes
An sRGB channel value is not proportional to light. The encoding applies a curve, so the value 128 is not half the light of 255 but about 21 percent of it. This is deliberate and useful: human vision is more sensitive to differences among dark tones than bright ones, so spending more of the available codes down there is a better use of eight bits.
It also means that any arithmetic on raw channel values is arithmetic on the wrong quantity. Averaging two colours by averaging their channels gives a result that is too dark. Computing a contrast ratio from raw values overstates the contrast of mid-tones, which is how an inaccurate checker passes a grey that a correct one fails. Resizing an image without linearising first is why downscaled images sometimes look muddier than the original.
The fix is always the same: undo the curve, do the arithmetic in linear light, put the curve back. The sRGB transfer function from IEC 61966-2-1 is a power of 2.4 with a short linear segment near black, which exists to keep the slope finite at zero rather than as a rounding convenience. Every conversion here goes through it.
Reading the contrast figure
WCAG 2 defines contrast as the lighter colour's relative luminance plus 0.05, divided by the darker's plus 0.05. The 0.05 accounts for ambient light reflecting off the screen, which is why the range tops out at 21:1 rather than at infinity: black on white gives (1 + 0.05) divided by (0 + 0.05), exactly 21.
That number is a useful check on any implementation. If a contrast tool tells you black on white is anything other than 21, it is not computing relative luminance correctly, and the most common reason is skipping the linearisation step.
The thresholds are 4.5:1 for normal text at AA, 3:1 for large text at AA, and 7:1 and 4.5:1 respectively at AAA. Large means 18pt or 14pt bold, roughly 24px and 19px bold on the web. It is worth knowing that WCAG 2's model has real limitations, particularly for light text on dark backgrounds, where it is widely agreed to be too permissive; the successor algorithm APCA addresses this and is not yet a normative requirement. Where the difference matters, test with your own eyes on a real screen as well.
Building a ramp that stays the same colour
The usual way to make a tint is to mix the colour toward white and the shade toward black. In sRGB that means interpolating channel values, and it drifts in two ways at once. Because the channels are gamma-encoded, the midpoint is not perceptually halfway. And because hue in RGB is an emergent property of the ratios between channels rather than a coordinate, moving all three toward 255 changes the ratios and therefore changes the hue. A saturated blue lightened this way passes through a washed-out lilac.
Working in OKLCH separates the three things you actually care about. Lightness, chroma and hue are coordinates, so you can raise lightness while holding the other two and the colour stays recognisably itself.
One further adjustment is needed. sRGB simply cannot hold much chroma near white or near black, so a ramp that keeps chroma flat pushes its lightest and darkest steps outside the gamut, where they clip to something duller and slightly off-hue. The ramp here tapers chroma toward both ends, which is what real design systems do and what makes the top and bottom of the scale usable rather than muddy.
Frequently asked questions
What is OKLCH and why should I use it?
A perceptually uniform colour space published by Björn Ottosson in 2020 and now part of CSS Color 4. The reason it matters is that HSL lies about lightness: hsl(60 100% 50%) is a bright yellow and hsl(240 100% 50%) is a dark blue, despite both claiming fifty percent. In OKLCH the same two are 97% and 45%, which is why equal steps in OKLCH look equal and equal steps in HSL do not.
Why does my palette look washed out when I lighten a colour?
Because mixing sRGB channels toward white ignores both gamma and the fact that blue is perceptually much darker than yellow. A saturated blue lightened that way passes through a grey-lilac on the way up. Holding hue and chroma while raising lightness in OKLCH avoids it, which is how the ramp here is built.
How is the contrast ratio worked out?
By the WCAG 2 definition: relative luminance of each colour computed on linear light, then the lighter plus 0.05 divided by the darker plus 0.05. The linear step is the one that gets skipped, and skipping it flatters mid-tones badly. Black on white gives exactly 21:1 here, which is the check that catches an implementation doing it on raw channel values.
What counts as large text for the AA threshold?
18pt, or 14pt bold, which is about 24px and 19px bold on the web. Large text needs 3:1 for AA and 4.5:1 for AAA; normal text needs 4.5:1 and 7:1. The thresholds exist because larger letterforms stay legible at lower contrast, not because the requirement is softer.
Which formats can I paste in?
Hex in three, four, six or eight digits, with or without the hash; rgb() and rgba() with commas or spaces and with or without percentages; hsl(); oklch() with lightness as a fraction or a percentage; and about thirty colour names. Alpha is read and ignored, since none of the conversions here depend on it.
Does converting lose accuracy?
Not to the nearest byte. A hex code converted to OKLCH and back lands on the same hex, which is checked against the reference values in the CSS Color 4 specification rather than only against itself.
Related calculators
Case Converter
Twelve cases, with title case that follows a style guide rather than capitalising everything.
OpenWord Counter
Words, characters and reading time, counted by Unicode rules rather than spaces.
OpenGraph Paper Generator
Squared paper at any spacing, printed to size.
Open