Parse HSL string to RGB
Read a pasted CSS color as numbers: hsl(210, 80%, 45%) becomes red 23, green 115 and blue 207, or #1773cf, whether you use commas, spaces or units such as deg and turn. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Hsl
- hsl(210, 80%, 45%)
- H
- 210
- S
- 80
- L
- 45
- Resistance (Ω)
- 23
Designers and engineers paste CSS hsl() and hsla() literals from stylesheets, Figma tokens, and browser DevTools, then need a stable red-green-blue triplet for canvases, native apps, and image buffers. This parser accepts a single CSS color string, tolerates extra spaces, optional hue units such as deg, turn, rad, and grad, and optional percent signs on saturation and lightness, then converts the parsed hue, saturation, and lightness through the same CSS Color Module path browsers use when they paint hsl(). Hue wraps the way CSS wraps angles; saturation and lightness outside zero to one hundred percent are rejected so a typo cannot silently become white.
How a CSS hsl() string becomes an RGB triplet
A CSS hsl() color names a point in cylindrical coordinates: hue is the angle around the wheel, saturation is how far the color sits from gray, and lightness is how close it sits to black or white. Hue may be a bare number of degrees or carry an explicit unit: deg, turn, rad, or grad. Saturation and lightness may include the percent sign or omit it; both are read as percentages from zero to one hundred.
After the token is understood, conversion follows the CSS Color Module and W3C hue2rgb path: scale saturation and lightness to the unit interval, compute intermediate bounds p and q, sample three shifted positions on the unit circle, multiply by two hundred fifty-five, and round to integers. When saturation is zero the three channels collapse to the same gray. The pipeline is pure arithmetic with no clocks and no network, so the same string always yields the same triplet.
Input contract, units, spacing, and error behaviour
The value must be a CSS hsl() or hsla() function, including the parentheses; a bare triple of numbers is rejected so the contract stays a string parser rather than a second numeric HSL form. Extra whitespace inside the parentheses is ignored. Saturation and lightness outside zero to one hundred percent also fail rather than clamp, so a typo such as five hundred percent cannot silently become white.
Hue wraps modulo three hundred sixty after unit conversion, matching CSS so four hundred eighty degrees and one hundred twenty degrees paint the same green. On success the body echoes the trimmed input string, the parsed numeric h, s, and l (hue in degrees after wrap, saturation and lightness as percentages), integer channels r, g, and b, an rgb array triplet, a printable rgb() string, a lowercase hex code, and a short formula note.
When the source string included an alpha component the response also includes a in the unit interval and an rgba() string; when alpha is absent those keys are omitted rather than set to null. Example: hsl(210, 80%, 45%) yields the same deep blue channels a numeric HSL converter would return for hue two hundred ten, saturation eighty, lightness forty-five.
Where parsing an hsl() string earns its keep
Design-token pipelines store brand ramps as CSS functions so they stay readable next to stylesheets, then emit integer channels for iOS UIColor, Android Color, and email hex. Visual-regression tools compare rendered pixels; a deterministic parse of the same hsl() string used in CSS is the only way to know the expected eight-bit triplet without opening a browser. Documentation generators print a swatch table from the tokens in a repository and must not invent a different green than the one the site ships.
Teaching materials that show CSS color functions beside RGB and hex need an oracle that reports malformed syntax instead of recovering from a missing percent sign by guessing. If you already have three numbers rather than a CSS string, use a numeric HSL-to-RGB converter; this landing owns the search intent for parsing an hsl() string into an RGB triplet.
What you can do with it
Stylesheet tokens to canvas and native RGB
Paste hsl() literals from a theme file or DevTools and obtain integer r, g, b plus hex for canvas fills, UIColor, and Android Color.
Design-token and documentation pipelines
Walk CSS function tokens in a design-system repository and emit a stable RGB triplet table that matches browser hsl() painting.
FAQ
What CSS hsl() forms does the parser accept?
Comma form hsl(h, s, l) and modern space form hsl(h s l), plus hsla() and optional alpha (fourth comma or slash). Extra spaces are ignored. Hue may use deg, turn, rad, or grad.
How is hsl() converted to an RGB triplet?
After the string is parsed, conversion follows the CSS Color Module hue2rgb path on the unit circle. Channels are rounded to integers 0–255. The same string always yields the same r, g, b.
What happens if the hsl() string is malformed?
Wrong function names, missing parentheses, the wrong number of components, mixed comma and slash syntax, and non-numeric tokens are rejected and not billed.
Do hue units wrap, and are saturation and lightness clamped?
Hue wraps modulo 360 after unit conversion, matching CSS. Saturation and lightness must lie between 0 and 100 percent; out-of-range values fail instead of clamping to white or black.
Can I paste a color straight from a stylesheet or DevTools?
Yes. Paste the whole hsl() or hsla() text, parentheses included, for example hsl(210, 80%, 45%). Extra spaces are ignored, but three bare numbers without the hsl() wrapper are turned down.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/color/hsl-string-to-rgb \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"hsl":"hsl(210, 80%, 45%)"}'const res = await fetch("https://api.kit.forhosting.com/color/hsl-string-to-rgb", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"hsl": "hsl(210, 80%, 45%)"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/hsl-string-to-rgb",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"hsl": "hsl(210, 80%, 45%)"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/hsl-string-to-rgb", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"hsl":"hsl(210, 80%, 45%)"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"hsl":"hsl(210, 80%, 45%)"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/hsl-string-to-rgb", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"hsl": "hsl(210, 80%, 45%)"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.hsl_string_to_rgb",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Malformed syntax—missing parentheses, the wrong function name, too few components, or non-numeric tokens—fails with invalid_input instead of guessing a nearby color.
How a CSS hsl() string becomes an RGB triplet
Authors write that point as a function token, not as three separate form fields, so a converter that only accepts numeric h, s, and l leaves a gap whenever the source of truth is a stylesheet, a design-token JSON file, or a DevTools copy. This capability parses the function token first. It accepts the historical comma form hsl(h, s, l) and the modern space-separated form hsl(h s l), with or without the a in hsla, and with an optional alpha after a fourth comma or after a slash.
Input contract, units, spacing, and error behaviour
POST a JSON body with one required string field named hsl. Aliases text, value, color, and input are accepted and mean the same thing. Missing hsl, an empty string, a string longer than two hundred fifty-six characters, a function name other than hsl or hsla, unbalanced parentheses, the wrong number of components, mixed comma and slash syntax, and tokens that are not finite numbers all fail with invalid_input and are not billed.
Where parsing an hsl() string earns its keep
Because this capability is a pure parse engine, the browser tool is free and a successful API call costs the published $0.002 per item; validation failures do not consume prepaid balance.
Integration use cases
Visual-regression fixtures
Turn the same hsl() strings your CSS ships into 8-bit RGB fixtures so screenshot tests compare against the color the browser will actually paint.
Technical questions
What does parsing an hsl() string to RGB cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.