HSL to HSV Color Converter
HSL and HSV share a hue angle but differ in how they encode brightness.
In HSL, a lightness of 100% always produces white, regardless of saturation, while a lightness of 50% at full saturation gives the most vivid version of the hue. In HSV, value 100% at full saturation gives the vivid color; white requires both value 100% and saturation 0%. This structural difference means the same color has different coordinates in each model, requiring explicit conversion when moving between tools that use each system.
How the conversion works
Converting HSL to HSV routes through intermediate lightness and chroma calculations. From the HSL lightness (L) and saturation (S), the algorithm computes the chroma C = S × (1 − |2L − 1|). From chroma and lightness, value V = L + C/2. Saturation in HSV is then S_hsv = C/V when V > 0, and 0 when V equals 0.1 The hue angle is identical in both models (no conversion is needed for that channel) because both HSL and HSV use the same 0–360 degree color wheel definition.
Why chroma matters in the conversion
Chroma represents the distance from the grey axis to the most saturated color at a given hue and lightness. It acts as the bridge between the two models because HSL and HSV both derive their third channel from chroma but apply it differently. In HSL, chroma determines how far the color deviates from the midpoint of lightness. In HSV, chroma determines how far the color deviates from black. Understanding this shared intermediate makes it clear why the two models produce different saturation and brightness coordinates for the same color.
Using chroma as the bridge also keeps the conversion exact for achromatic colors. When saturation is zero in HSL, the chroma is zero, so the computed value collapses to the HSL lightness with no residual color, which matches how black and white behave in HSV. That clean collapse is why the same formula works from the most vivid hue down to pure grey without a separate code path for achromatic inputs.
Where this comes up
Graphics APIs and native OS color pickers often use HSV rather than HSL. Photoshop's color picker reports HSB (which is identical to HSV: the "B" stands for brightness, a synonym for value). Many OpenCV and image processing functions accept HSV natively. Consequently, converting HSL design tokens to HSV is a common step when a web workflow feeds into a desktop graphics pipeline. Furthermore, color picker UI components in JavaScript (react-colorful, pickr, and others) internally use HSV to determine the position of the gradient thumb.
When web and desktop pipelines intersect
A typical crossover happens when a design system defines colors as HSL tokens for CSS, but the same colors must be entered into a desktop image editor like Photoshop or Affinity Designer. Those applications expose an HSB/HSV picker, not an HSL one. Rather than manually approximating values, match an HSL token to Photoshop's HSB fields once during handoff, which eliminates guesswork and ensures the color rendered on the web page matches what the designer sees in their editing tool.
Edge cases and rounding
Achromatic inputs (HSL saturation 0) produce HSV saturation 0 regardless of value; the hue remains 0° by convention. HSL lightness 100% (white) converts to HSV value 100% and saturation 0%. HSL lightness 0% (black) converts to HSV value 0% and saturation 0%. Intermediate rounding may shift saturation by 0.1–0.2 percentage points. Building on this, any round-trip of HSL → HSV → HSL should validate against the original rather than assuming perfect reversibility for non-integer input values.
Why pure white and pure black behave differently
In HSL, white (lightness 100%) and black (lightness 0%) are the only two points where saturation has no visible effect. When you convert these to HSV, the saturation drops to 0% and the value matches the lightness extremes. This matters when you are building a color scale that includes both endpoints: a scale from hsl(217, 91%, 0%) through hsl(217, 91%, 100%) will have correct HSV saturation at the midpoint but zero saturation at both ends, which means any hue rotation you apply at the extremes will have no visible effect.
Why Photoshop uses HSB and how to match its values
Photoshop's color picker displays HSB (Hue, Saturation, Brightness) values, which are identical to HSV under a different name. When a designer gives you HSB values from Photoshop (for example, H: 217, S: 76%, B: 96%), you can use them as direct HSV input. The conversion from HSL to HSV is necessary because your CSS design tokens likely use HSL, and the Photoshop values are in a different color model.
The structural difference between HSL and HSV is in how they handle lightness versus value. HSL lightness 50% at full saturation gives the most vivid color; HSV value 100% at full saturation gives the same vivid color. But HSL lightness 75% produces a pastel, while HSV value 100% at a lower saturation also produces a pastel, through a different numeric path. Building on this, when you convert an HSL design token to HSV for Photoshop input, the saturation and brightness values will be different from the HSL saturation and lightness, even though the resulting color is the same. This is expected and correct.
OpenCV color space conversions and HSV ranges
OpenCV uses HSV with a specific range: H is 0–180 (not 0–360), S is 0–255, and V is 0–255.2 This is a quirk of the library's 8-bit integer representation, which halves the hue range to fit in a single byte. When you convert HSL to HSV for use in OpenCV, you must scale the hue angle by dividing by 2 and scale saturation/value to 0–255 instead of 0–100%.
For example, hsl(217, 91%, 60%) converts to hsv(217, 76%, 80%) in standard HSV. In OpenCV's representation, this becomes H: 108 (217 / 2), S: 194 (76% of 255), V: 204 (80% of 255). Building on this, if you are building a web interface that lets users pick colors in HSL and then processes images with OpenCV on the backend, the conversion pipeline is: HSL → standard HSV → OpenCV HSV (with range scaling). Getting the scaling wrong produces colors that are visibly wrong, so test with known reference values before deploying.
JavaScript color picker internals: why most use HSV
Most JavaScript color picker libraries (react-colorful, pickr, Spectrum) use HSV internally for their color space model.3 The reason is that HSV maps naturally to the visual layout of a color picker: the hue is represented as a vertical or circular gradient, the saturation as a horizontal axis (from grey to full color), and the value as a vertical axis (from black to full brightness). This three-dimensional layout is intuitive for users and straightforward to implement with CSS gradients.
When you initialize a color picker with an HSL value, the library converts HSL to HSV internally, then uses the HSV coordinates to position the picker's thumbs and gradients. The conversion happens once at initialization. Building on this, if you are building a custom color picker and want to accept HSL input, you need to implement the HSL-to-HSV conversion yourself or use a library like culori that provides it. The converter on this tool performs this conversion and displays the HSV output, which you can then pass directly to your color picker's initialValue prop.
When to use this
Use this when transferring a color defined in HSL to an API, library, or design tool that accepts only HSV (or HSB) coordinates, most notably Photoshop, OpenCV, and JavaScript color picker components.
Examples
CSS HSL token → Photoshop HSB input
hsl(74, 100%, 50%)
hsv(74, 100%, 100%)
In Photoshop, H/S/B fields map directly to these HSV values.
Hover state HSL → color picker library init
hsl(217, 91%, 50%)
hsv(217, 97%, 80%)
Pass the HSV triple to color picker initializers that use the HSV model.
- 1.
"HSL and HSV," Wikipedia, en.wikipedia.org, accessed June 2026. https://en.wikipedia.org/wiki/HSL_and_HSV
- 2.
OpenCV, "Changing Colorspaces," docs.opencv.org, accessed June 2026. https://docs.opencv.org/4.x/df/d9d/tutorial_py_colorspaces.html
- 3.
omgovich, "react-colorful/src/hooks/useColorManipulation.ts," github.com, accessed June 2026. https://github.com/omgovich/react-colorful/blob/master/src/hooks/useColorManipulation.ts