HSL to HEX converter
Convert hsl() or hsla() values into a hex colour code, with a live swatch and every other CSS notation listed alongside it.
- Runs in your browser
- Nothing you enter is sent
- Free, no account
Hue in degrees, then saturation and lightness as percentages.
Converted from HSL.
Contrast on white
5.20:1
AA for body text
Contrast on black
4.04:1
AA for large text only
| Format | Value | Copy |
|---|---|---|
| HEX | #2463eb | |
| HEX with alpha | #2463ebff | |
| RGB | rgb(36, 99, 235) | |
| RGBA | rgba(36, 99, 235, 1) | |
| RGB (space syntax) | rgb(36 99 235) | |
| HSL | hsl(221, 83%, 53%) | |
| HSLA | hsla(221, 83%, 53%, 1) | |
| HSL (space syntax) | hsl(221 83% 53%) | |
| HSV / HSB | hsv(221, 84.8%, 92%) | |
| CMYK | cmyk(84.8%, 57.9%, 0%, 8%) | |
| Android ARGB | #FF2463EB | |
| SwiftUI | Color(red: 0.141, green: 0.388, blue: 0.922) | |
| Nearest CSS name | royalblue (closest match) |
CSS custom properties
--color: #2463eb; --color-rgb: 36 99 235; --color-hsl: 221 83% 53%;
Your colour values never leaves this tab — check it yourself—
Starting the network probe…
The counter above wraps fetch, XMLHttpRequest and navigator.sendBeacon in this tab and counts every call. It does not block anything — it just reports.
Two ways to verify independently
- Turn off Wi-Fi or enable airplane mode, then use the tool. It keeps working, because the page is already fully loaded.
- Open your browser devtools, switch to the Network tab, clear it, and run the tool. No new row appears.
Why this matters
In 2025 researchers found that popular online formatters had retained tens of thousands of user-submitted snippets — JSONFormatter.org and CodeBeautify together exposed roughly 80,000 saved documents, many containing live cloud credentials, private keys and internal database connection strings, because “format this” quietly meant “upload this”. A separate incident exposed roughly 3.5 million user PDFs on a document-conversion service. The only structural fix is not sending the data in the first place: this site is served under a Content-Security-Policy whose connect-src contains no third-party origin, so a request off this device cannot be made even by accident.
The conversion
HSL to RGB works by finding the chroma — how much colour there is at this lightness — then placing it on the right pair of channels according to which 60-degree sector of the wheel the hue falls in.
hsl(221, 83%, 53%)
C = (1 - |2L - 1|) × S = (1 - 0.06) × 0.83 = 0.780
X = C × (1 - |(H/60) mod 2 - 1|) = 0.078
m = L - C/2 = 0.140
H = 221 is in the 180–240 sector → (r,g,b) = (0, X, C)
r = (0 + 0.140) × 255 = 36
g = (0.078 + 0.140) × 255 = 56
b = (0.780 + 0.140) × 255 = 234
#2438ea Every intermediate value is kept in floating point and rounded only at the last step, which is why round-tripping a hex code through HSL and back returns the original byte.
What you can paste
hsl(221, 83%, 53%)— the comma syntax.hsl(221 83% 53% / 50%)— the modern space syntax with alpha.hsla(221, 83%, 53%, 0.5)— alpha as 0 to 1.221 83% 53%— a bare triple with percent signs, which is what a design token often stores.
Hue wraps, so 380 is treated as 20 and −40 as 320. Saturation and lightness are clamped to 0–100.
Why your hex might differ by one
HSL is continuous and hex is a grid of 16.7 million points, so the conversion snaps to the nearest
representable colour. Rounding a hue to a whole degree before converting can move a channel by one
— hsl(220.9, …) and hsl(221, …) are not quite the same colour. If you are
trying to reproduce an exact hex value, convert in the other direction and copy the full-precision
HSL from the table rather than the rounded display value.
Storing HSL in a design system
A pattern worth knowing: store the three channel values without the function wrapper in a custom property, then compose them where needed.
:root {
--brand: 221 83% 53%;
}
.button {
background: hsl(var(--brand));
}
.button:hover {
background: hsl(221 83% 45%);
}
.button-tint {
background: hsl(var(--brand) / 12%);
}
That gives you one source of truth for the hue and free alpha variants, without a preprocessor.
The same trick works with rgb() and space-separated channels.
What about oklch?
Oklch is genuinely better for building scales, because equal lightness steps look equal across different hues in a way HSL steps do not. This converter deliberately does not emit it: a correct sRGB↔Oklab conversion involves a gamma transfer function and a matrix multiply, and a colour-code page that got it subtly wrong would be worse than one that does not try. Convert to hex here and use a dedicated Oklch tool for wide-gamut work.
Questions
What input does it accept?
`hsl(221, 83%, 53%)`, the space syntax `hsl(221 83% 53% / 50%)`, `hsla()` with a 0–1 alpha, and a bare triple with percent signs such as `221 83% 53%`. Hue wraps, so 380 is treated as 20.
Why does my hex look slightly different from the HSL I typed?
Rounding. HSL is continuous and hex is a 24-bit grid, so the conversion snaps to the nearest representable colour. Round-tripping hex → HSL → hex always returns the original byte; round-tripping in the other direction can shift a hue by a fraction of a degree.
Should I ship HSL or hex in my CSS?
Either — browsers treat them identically. HSL is easier to maintain in a design-token file because a whole scale can be derived from one hue. Hex is easier to paste between tools. Many teams store HSL channel values in a custom property and compose them where needed.
What about oklch and other modern colour spaces?
They are genuinely better for perceptual uniformity, and this converter does not emit them, because a correct sRGB-to-Oklab conversion needs more care than a colour-code page should hide. Convert to hex here and use a dedicated tool for wide-gamut work.