HSL to RGB Converter
Optional shortcut — sets the fields below. No transparency support (a browser limitation of this control), so use the HEX/RGB/HSL fields directly for a translucent color.
#RGB, #RGBA, #RRGGBB, or #RRGGBBAA — the # is optional
rgb(R, G, B) or rgba(R, G, B, A) — R/G/B 0-255, A 0-1
hsl(H, S%, L%) or hsla(H, S%, L%, A) — H 0-360, A 0-1
However an HSL color was chosen or generated, it has to become RGB before it can actually be drawn — every display is built from red, green, and blue light-emitting sub-pixels, and modern browsers’ native hsl() CSS support is really just the browser doing this exact conversion for you invisibly. The moment you’re working below that convenience layer — a Canvas 2D context’s numeric APIs, a WebGL shader’s color uniform, an ImageData buffer you’re writing pixels into directly — HSL stops being accepted automatically, and converting it to RGB yourself becomes a required step, not an optional one.
The formula (the reverse of RGB-to-HSL) reconstructs three RGB channels from hue, saturation, and lightness using a piecewise function over six 60°-wide segments of the color wheel — which segment the hue falls in determines which of the three RGB channels is rising, which is falling, and which is holding steady. hsl(340, 82%, 52%) — a hue just past magenta, heading back toward red — works out to rgb(233, 32, 99): a vivid pink-red, with red as the dominant channel, blue as a strong secondary component (magenta’s influence), and green suppressed almost to nothing. Unlike the RGB-to-HSL direction, where hue/saturation/lightness get rounded to whole numbers for display, RGB channels are always whole numbers by definition — 0 to 255, nothing in between — so this direction’s rounding happens at the very end of the calculation rather than being a display-only concern.
One place this conversion shows up as a genuinely useful technique, not just a necessary chore: generating a set of visually distinct colors programmatically — a chart’s category palette, a set of user-avatar background colors, tag/label colors — is far easier in HSL than in RGB. Holding saturation and lightness constant and stepping the hue evenly around the 360° wheel (dividing 360 by the color count) produces colors that are maximally, evenly spread apart with almost no effort; there’s no equivalently simple formula for “N evenly distinct colors” starting from RGB directly. Each generated HSL value still needs converting to RGB (or hex) before a canvas or chart library can actually paint it.
Converting HSL to RGB programmatically
JavaScript, plus a practical batch example — generating an evenly-spaced palette for a chart:
function hueToChannel(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
function hslToRgb(h, s, l) {
const hn = h / 360, sn = s / 100, ln = l / 100;
if (sn === 0) {
const v = Math.round(ln * 255);
return { r: v, g: v, b: v };
}
const q = ln < 0.5 ? ln * (1 + sn) : ln + sn - ln * sn;
const p = 2 * ln - q;
return {
r: Math.round(hueToChannel(p, q, hn + 1 / 3) * 255),
g: Math.round(hueToChannel(p, q, hn) * 255),
b: Math.round(hueToChannel(p, q, hn - 1 / 3) * 255),
};
}
console.log(hslToRgb(340, 82, 52));
// { r: 233, g: 32, b: 99 }
// A 5-color chart palette, hues evenly spaced around the wheel:
const palette = Array.from({ length: 5 }, (_, i) => hslToRgb((i * 360) / 5, 70, 55));
Python, via colorsys.hls_to_rgb (hue, lightness, saturation order):
import colorsys
r, g, b = colorsys.hls_to_rgb(340 / 360, 0.52, 0.82)
print(round(r * 255), round(g * 255), round(b * 255))
# 233 32 99Frequently asked questions
Why can't a browser or a canvas just render an HSL color directly?
hsl() as a value, but that's the browser converting it to RGB internally before it ever reaches a pixel — every physical display renders through red, green, and blue sub-pixels, full stop, so an HSL value has to become RGB channel intensities at some point no matter what wrote it. Canvas's 2D context, WebGL shader uniforms, and most lower-level graphics APIs skip that convenience layer entirely and expect RGB (or raw channel numbers) directly, which is when converting HSL to RGB yourself becomes necessary rather than automatic.How do I generate a set of evenly-spaced colors using HSL?
Does the RGB result always land on whole numbers?
What happens to alpha in this conversion?
Is my color sent to a server?
Related Color Converter pages
Looking for a different pair or algorithm? Here are the other specific versions, plus the general tool for everything else: