ToolJutsu
All tools
Color & Design Tools

RGB to HSL

Convert rgb() colours to hsl() for tints and shades.

hsl() output

hsl(186, 100%, 50%)

Processed on your device. We never see your files.

How to use RGB to HSL

What is the rgb() function?

rgb() is the canonical CSS notation for an sRGB colour, written as three decimal channels from 0 to 255 — for example rgb(255, 0, 0) for pure red. Each channel represents the intensity of one additive primary: red, green or blue. Mix all three at full strength and you get white; set them all to zero and you get black. The format is the lingua franca of JavaScript colour libraries, design tokens and any pipeline that thinks of colour as three integers rather than a packed hex string.

What is HSL?

HSL stands for Hue, Saturation, Lightness — a coordinate system designed to be readable by humans. Hue is an angle on the colour wheel from 0° to 360°: 0° is red, 120° green, 240° blue, and the wheel wraps back to red at 360°. Saturation is how colourful the result is, from 0% (a pure grey) to 100% (as vivid as the hue allows). Lightness runs from 0% (black) through 50% (the most saturated version of the hue) up to 100% (white). The format is the natural home for programmatic colour-scale generation: keep one channel constant and step another to derive tints and shades from a single base.

The conversion math

Normalise the three channels by dividing each by 255, giving values in 0–1. Find the max and min of the three. Lightness is the midpoint: L = (max + min) / 2. If max equals min, the colour is achromatic — saturation is 0 and hue is undefined (the converter emits 0 by convention). Otherwise, saturation depends on lightness: S = (max - min) / (1 - |2L - 1|). Hue is computed from which channel held the max and the difference between the other two, then mapped to 0–360°. The result is rounded for display: hue to whole degrees, saturation and lightness to whole percents.

Use cases

Programmatic colour scales. Generating a 10-step tint ramp from a single base colour is dramatically easier in HSL than in RGB — keep hue and saturation constant, step lightness from 95% down to 10%, and you have a coherent scale. Converting your RGB base to HSL is the first step.

CSS authoring. When the brand stylesheet wants colours expressed in HSL for readability (it’s obvious at a glance that hsl(210, 80%, 45%) is a blue), but your source values are RGB from a design tool, this converter is the bridge.

Design systems. Token pipelines often normalise base colours into HSL before deriving variants, so the conversion is built into the build step.

Accessibility tweaks. When a colour fails a WCAG contrast check against a background, bumping lightness while keeping hue and saturation constant is the simplest fix. HSL makes the single-axis adjustment trivial.

JavaScript colour manipulation. Libraries like chroma.js and color let you pass HSL strings or component values directly, which keeps derivative-colour code legible.

Pitfalls

  • HSL is not HSV. Photoshop uses HSV (the third channel is “value” / brightness, not “lightness”). The numbers look similar but mean different things. CSS only accepts HSL.
  • HSL lightness is not perceptual. A lightness: 50% yellow looks much brighter than a lightness: 50% blue. For perceptually-uniform lightness use OKLCH or HSLuv, both outside the scope of this landing.
  • Hue is undefined for greys. When R = G = B, HSL hue has no meaningful value — the converter emits 0 by convention. Don’t read meaning into the hue of a grey.
  • Alpha not preserved. rgba() input loses its alpha here; use the Color Converter for alpha-aware HSL (HSLA) output.
  • Out-of-range channels. Values above 255 or below 0 aren’t valid rgb(); the converter clamps them and tells you it did.

How to use this RGB to HSL converter

  1. Paste your rgb() value into the input. The parens and commas are optional; 255, 0, 0 and rgb(255 0 0) both work.
  2. The hsl(h, s%, l%) output and the colour swatch update live — no Convert button.
  3. If a channel is out of range or non-numeric, a friendly inline message points at the problem.
  4. Tap Copy to put the HSL string on your clipboard.

Privacy

The conversion is a small JavaScript function running locally in your browser tab. No server calls, no logging, no analytics on your colour values. The page caches its bundle on first load and works fully offline thereafter.

Compatibility notes

hsl() notation is supported in every browser since IE9 (2011), so it’s safe to use anywhere. The output uses comma-separated form (hsl(210, 80%, 45%)) because that’s still the most widely compatible and what CSS linters accept by default. The modern slash-separated syntax (hsl(210 80% 45% / 1)) is available in the Color Converter when you need alpha-aware modern CSS.

Frequently asked questions

What rgb() formats does this accept?
Both the canonical rgb(r, g, b) with parentheses and commas, and the bare triplet r, g, b (or space-separated r g b). Each channel must be an integer from 0 to 255 — float and percentage inputs are rounded to the nearest integer before conversion. The output is always emitted as hsl(h, s%, l%) with comma separators because that's still the most widely-compatible form across browsers and CSS linters.
Why does the same RGB value sometimes show a hue of 0?
When the red, green and blue channels are equal — like rgb(128, 128, 128) — the colour is a pure grey with no hue at all. The HSL spec defines hue as undefined for greyscale colours, but every browser (and this converter) reports it as 0 by convention. Saturation is 0%, lightness is whatever the channel value implies, and the hue value is essentially a placeholder you can ignore. The same goes for pure black and pure white.
Why are saturation and lightness sometimes counter-intuitive?
Because HSL maps lightness as the midpoint of max and min channels, not as perceptual brightness. A pure yellow rgb(255, 255, 0) reports lightness: 50% — the same as a much darker red like rgb(128, 0, 0) — because mathematically both sit at the lightness midpoint of their hue. To a human, yellow looks much brighter. For perceptually-uniform lightness use OKLCH or HSLuv instead of HSL.
What's the difference between HSL and HSV?
They share the same hue and saturation logic but the third channel is different. HSL's lightness runs from black (0%) through the most-saturated form of the hue (50%) up to white (100%). HSV's value (sometimes called brightness) runs from black (0%) up to the most-saturated form of the hue (100%) — white doesn't exist in HSV except as 0% saturation at 100% value. Photoshop uses HSV; CSS uses HSL. Don't confuse them.
Is my colour data uploaded anywhere?
No. The RGB-to-HSL math runs entirely in your browser as a small JavaScript function. No server call, no logs, no analytics on the values you enter. The page caches its bundle on first load and from then on works fully offline. Confirm in the browser's Network panel that there are no outbound requests when you paste an rgb() value.

Related tools