HEX to HSL 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
A hex code and its HSL equivalent describe the same color, but only one of them is easy for a person to reason about. #7c3aed tells you nothing at a glance about whether the color is vivid or muted, light or dark, or what happens if you nudge it slightly — the three hex pairs are red, green, and blue channel bytes, and changing “just the lightness” means recalculating all three together, by trial and error. HSL separates the same color into three independent, meaningful knobs: hue (which color, as a position on a 360° wheel), saturation (how intense or muted), and lightness (how light or dark) — turning “make this a bit lighter” from a guessing game into changing one number.
Getting from hex to HSL is genuinely a two-step process, not one: hex encodes RGB channel bytes, not hue/saturation/lightness directly, so the first step splits the hex string into red, green, and blue (the same parsing a hex-to-RGB conversion does), and only the second step runs the actual HSL math over those three channel values — comparing which channel is largest and smallest to derive hue, and how far apart they are to derive saturation. There’s no shortcut that skips the RGB step, because HSL’s definition is built entirely on the relationships between the RGB channels, not on the hex digits themselves.
Taking this specific color as an example: #7c3aed converts to hsl(262, 83%, 58%). The hue, 262°, sits just past blue (240°) heading toward magenta — the blue-violet/purple range, matching what the color actually looks like. An 83% saturation is close to fully vivid (100% would be as intense as that hue can get; 0% would be gray), which is why the color reads as a bold, saturated purple rather than a muted lavender. A 58% lightness sits just above the midpoint, giving a color that’s neither washed-out pale nor near-black — reading each of the three numbers this way is exactly the point of converting to HSL in the first place.
Converting hex to HSL programmatically
JavaScript, as the two explicit steps described above:
function hexToRgb(hex) {
const h = hex.replace("#", "");
return {
r: parseInt(h.slice(0, 2), 16),
g: parseInt(h.slice(2, 4), 16),
b: parseInt(h.slice(4, 6), 16),
};
}
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b), min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
if (max === r) h = (g - b) / d + (g < b ? 6 : 0);
else if (max === g) h = (b - r) / d + 2;
else h = (r - g) / d + 4;
h *= 60;
}
return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };
}
const { r, g, b } = hexToRgb("#7c3aed");
console.log(rgbToHsl(r, g, b));
// { h: 262, s: 83, l: 58 }
Python, using the standard library’s colorsys for the RGB→HSL step (note: colorsys calls it rgb_to_hls — hue, lightness, saturation, in that order — not hsl):
import colorsys
def hex_to_rgb(hex_color):
h = hex_color.lstrip("#")
return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
r, g, b = hex_to_rgb("#7c3aed")
h, l, s = colorsys.rgb_to_hls(r / 255, g / 255, b / 255)
print(round(h * 360), round(s * 100), round(l * 100))
# 262 83 58Frequently asked questions
Why convert hex to HSL instead of just adjusting the hex digits directly?
#7c3aed lighter by hand means recalculating all three channel pairs together and guessing; in HSL, it's one number: raise the lightness percentage and every other property of the color (its hue, how saturated it is) stays exactly the same.Why can't hex convert to HSL in a single step?
What does this color's hue of 262° actually mean?
#7c3aed visually. Moving the hue up or down from there without touching saturation or lightness shifts the color around the wheel while keeping it equally vivid and equally bright.Is 83% saturation considered vivid or muted?
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: