@nauverse/color-to-hsla
v2.0.0
Published
A tiny, dependency-free TypeScript library to convert any CSS color (hex, rgb, hsl, named colors, modern CSS syntax) to HSLA.
Maintainers
Readme
tl;dr
npm install @nauverse/color-to-hslaimport { colorToHSLA, hslaToString } from "@nauverse/color-to-hsla";
colorToHSLA("rgb(255 0 0 / 50%)");
// { h: 0, s: 1, l: 0.5, a: 0.5 }
hslaToString({ h: 120, s: 0.5, l: 0.5, a: 0.25 });
// "hsla(120, 50%, 50%, 0.25)"Why color-to-hsla?
Most apps only need one thing from a color library: turning whatever color a user, a design token or a CSS file gives you into numbers you can work with. color-to-hsla does exactly that, for every CSS color syntax, and always returns a normalized result: the hue is an integer from 0 to 359, and the saturation, the lightness and the alpha go from 0 to 1.
color-to-hsla vs other libraries
Every result below was produced by running the libraries (tinycolor2 1.6.0, color 5.0.3, culori 4.0.2, color-to-hsla 2.0.0):
| Input | tinycolor2 | color | culori | color-to-hsla |
| ----- | ---------- | ----- | ------ | ------------- |
| rgb(255 0 0 / 50%) | Alpha lost (a: 1) | Correct | Correct | { h: 0, s: 1, l: 0.5, a: 0.5 } |
| rgba(255, 0, 0, 50%) | Alpha lost (a: 1) | Correct | Correct | { h: 0, s: 1, l: 0.5, a: 0.5 } |
| hsl(120deg 50% 50%) | Invalid | Correct | Correct | { h: 120, s: 0.5, l: 0.5, a: 1 } |
| hsl(0.5turn 50% 50%) | Invalid | Throws | Correct | { h: 180, s: 0.5, l: 0.5, a: 1 } |
| hsl(-120, 50%, 50%) | Wrong hue (h: 0) | Correct | Hue not normalized (h: -120) | { h: 240, s: 0.5, l: 0.5, a: 1 } |
| rgb(300, 0, 0) | Clamped | Clamped | Not clamped (s: 1.43) | Clamped: { h: 0, s: 1, l: 0.5, a: 1 } |
| Result scale | 0-1 | 0-100 | 0-1, alpha only when set | 0-1, always with alpha |
| Invalid string | Flag to check | Throws | undefined | { h: 0, s: 0, l: 0, a: 0 } |
| Size (minified + gzipped, only what the example needs) | 5.3 kB | 8.5 kB | 5.0 kB | 2.9 kB, zero dependencies |
Choose culori or color if you need other color spaces (Lab, OKLCH, P3...), color manipulation or conversions to other formats. Choose color-to-hsla if you need HSLA, fast, with no dependencies and no surprises.
Features
- Every CSS syntax of hex colors (
#f00,#f008,#ff0000,#ff000080),rgb(),rgba(),hsl()andhsla() - Legacy (
rgb(255, 0, 0)) and modern (rgb(255 0 0 / 50%)) syntaxes, percentages,none, and hue units (deg,grad,rad,turn) - All 148 CSS named colors and
transparent - Objects:
{ h, s, l, a }and{ r, g, b, a } - Normalized results: wrapped hue, clamped values, no floating point noise
- Never throws on strings: invalid colors return a transparent black
hslaToStringto go back to CSS- Zero dependencies, ESM and CommonJS builds, TypeScript types included
Installation
npm install @nauverse/color-to-hsla// ESM
import { colorToHSLA, hslaToString } from "@nauverse/color-to-hsla";
// CommonJS
const { colorToHSLA, hslaToString } = require("@nauverse/color-to-hsla");It runs in every modern browser and in Node.js 22 and later.
Guide
colorToHSLA
colorToHSLA takes a CSS color string or a color object and returns { h, s, l, a }:
h: the hue, an integer from 0 to 359s: the saturation, from 0 to 1l: the lightness, from 0 to 1a: the alpha, from 0 to 1
Hex colors
colorToHSLA("#f00");
// { h: 0, s: 1, l: 0.5, a: 1 }colorToHSLA("#FF0000");
// { h: 0, s: 1, l: 0.5, a: 1 }colorToHSLA("#ff000080");
// { h: 0, s: 1, l: 0.5, a: 0.5019607843 }rgb() and rgba()
colorToHSLA("rgb(255, 0, 0)");
// { h: 0, s: 1, l: 0.5, a: 1 }colorToHSLA("rgb(100%, 0%, 0%)");
// { h: 0, s: 1, l: 0.5, a: 1 }colorToHSLA("rgba(255, 0, 0, 0.5)");
// { h: 0, s: 1, l: 0.5, a: 0.5 }colorToHSLA("rgb(255 0 0 / 50%)");
// { h: 0, s: 1, l: 0.5, a: 0.5 }hsl() and hsla()
colorToHSLA("hsl(120, 50%, 50%)");
// { h: 120, s: 0.5, l: 0.5, a: 1 }colorToHSLA("hsla(120, 50%, 50%, 0.3)");
// { h: 120, s: 0.5, l: 0.5, a: 0.3 }colorToHSLA("hsl(0.5turn 50% 50% / 25%)");
// { h: 180, s: 0.5, l: 0.5, a: 0.25 }Named colors and transparent
colorToHSLA("rebeccapurple");
// { h: 270, s: 0.5, l: 0.4, a: 1 }colorToHSLA("transparent");
// { h: 0, s: 0, l: 0, a: 0 }Normalization
Hues wrap around, and every other value is clamped, like CSS does:
colorToHSLA("hsl(-120, 150%, 50%)");
// { h: 240, s: 1, l: 0.5, a: 1 }colorToHSLA("rgba(300, 0, 0, 2)");
// { h: 0, s: 1, l: 0.5, a: 1 }Invalid colors
Strings never throw: an invalid color returns a transparent black.
colorToHSLA("not a color");
// { h: 0, s: 0, l: 0, a: 0 }Objects
HSL objects use a saturation and a lightness from 0 to 1, RGB objects use channels from 0 to 255. The alpha is optional (1 by default):
colorToHSLA({ h: 120, s: 0.5, l: 0.5 });
// { h: 120, s: 0.5, l: 0.5, a: 1 }colorToHSLA({ r: 255, g: 0, b: 0, a: 0.5 });
// { h: 0, s: 1, l: 0.5, a: 0.5 }Objects must be complete: a missing or non-numeric value, or a mix of HSL and RGB keys, throws. Keys set to undefined are ignored.
colorToHSLA({ h: 120 });
// Throws: Missing key "s" in color type hslhslaToString
hslaToString converts an HSLA object to a CSS string. The hue wraps around, the saturation and the lightness are rounded percentages, and the alpha keeps up to three decimals:
hslaToString({ h: 120, s: 0.5, l: 0.5, a: 1 });
// "hsla(120, 50%, 50%, 1)"hslaToString({ h: -30, s: 0.5, l: 0.5, a: 0.125 });
// "hsla(330, 50%, 50%, 0.125)"TypeScript
The package includes its type definitions: HSLA (the result) and IColorObject (the accepted objects: IHSLColorObject | IRGBColorObject). Partial objects are type errors.
Upgrading from 1.x
Version 2 fixes many wrong results, so some of them change:
- Node.js 22 or later is required.
blackreturneda: 0(it was taken as an unknown color). It now returnsa: 1.- The modern CSS syntax, percentage alphas, hue units and
#rgba/#rrggbbaahex colors are supported (they returned{ h: 0, s: 0, l: 0, a: 0 }). - Hues wrap around (from 0 to 359) and decimal hues are rounded instead of truncated.
- Channels, saturation, lightness and alpha are clamped (
rgb(300, 0, 0)gave a saturation above 1). - Values have no floating point noise (
0.49999999999999994is0.5), since they are rounded to 10 decimals. - Partial or non-numeric objects throw (the missing values were taken as 0), and
nullthrows a clear error. TheIColorObjecttype only accepts complete objects, and the types are exported (they were not). - Parsing follows CSS Color 4 more strictly: only CSS whitespace is accepted (not other Unicode spaces), the legacy
rgb()syntax can not mix numbers and percentages, and numbers need digits after a dot (1.is invalid). Newlines inside a color and modern values without spaces between tokens (rgb(10%20%30%)) are accepted. hslaToStringwraps the hue (-30gave0) and keeps up to three alpha decimals (0.05gave0.1).
Help
Thank you for using color-to-hsla!
If you need any help using this library, feel free to create a GitHub issue and ask your questions. I'll try to answer as quickly as possible.
Contribute
Contributions of any kind (pull requests, bug reports, feature requests, documentation, design) are more than welcome! Read the contributing guide to get started (and AGENTS.md if you use a coding agent).
Contributors
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
