# How can I convert between hexadecimal, RGB, HSL and HSB color formats in JavaScript?

Working with colors often requires converting between different formats, such as hexadecimal, RGB, HSL and HSB. This can be useful when you need to manipulate colors in a specific format, or when you want to display them in a different way.

## Color formats

Before diving into conversion formulas, it's worth discussing the different color formats briefly:

**Hexadecimal**: A**6-digit hexadecimal representation**of a color, with 2 digits for each of the red, green and blue components. For example,`#ff0000`

represents the color red.**RGB**: A**comma-separated list of the red, green and blue components**of a color, each ranging from 0 to 255. For example,`rgb(255, 0, 0)`

represents the color red.**HSL**: A**comma-separated list of the hue, saturation and lightness components**of a color, with the hue ranging from 0 to 360, and the saturation and lightness ranging from 0% to 100%. For example,`hsl(0, 100%, 50%)`

represents the color red.**HSB**: A**comma-separated list of the hue, saturation and brightness components**of a color, with the hue ranging from 0 to 360, and the saturation and brightness ranging from 0% to 100%. For example,`hsb(0, 100%, 100%)`

represents the color red.

## RGB to hexadecimal

Converting between RGB and hexadecimal color formats is a matter of **converting the red, green and blue components to their hexadecimal representation**. This can be done using `Number.prototype.toString()`

combined with the `<<`

(left-shift) operator to convert the RGB components to a 6-digit hexadecimal value. Finally, we can use `String.prototype.padStart()`

to ensure that the hexadecimal value is 6 digits long.

const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); rgbToHex(255, 165, 1); // 'ffa501'

## Hexadecimal to RGB

Converting the other way round, from hexadecimal to RGB, is a little more involved. In order to **isolate the color components** from the hexadecimal string, we'll have to use bitwise right-shift and mask bits with `&`

(and) operator.

Additionally, we need to account for the possibility of an **alpha channel**, which would require returning an `rgba()`

string instead of an `rgb()`

string. Moreover, we should also handle the case where the hexadecimal value is only **3 digits long**, by converting it to a 6-digit version before extracting the components. Finally, we need to make sure to trim a possible `#`

**prefix** from the hexadecimal string.

const hexToRgb = hex => { let alpha = false, h = hex.slice(hex.startsWith('#') ? 1 : 0); if (h.length === 3) h = [...h].map(x => x + x).join(''); else if (h.length === 8) alpha = true; h = parseInt(h, 16); return ( 'rgb' + (alpha ? 'a' : '') + '(' + (h >>> (alpha ? 24 : 16)) + ', ' + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + ', ' + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + (alpha ? `, ${h & 0x000000ff}` : '') + ')' ); }; hexToRgb('#27ae60ff'); // 'rgba(39, 174, 96, 255)' hexToRgb('27ae60'); // 'rgb(39, 174, 96)' hexToRgb('#fff'); // 'rgb(255, 255, 255)'

## RGB to HSL

As the math behind colorspace conversions can be quite complex, delving into details of the conversion formula is beyond the scope of this article. Implementing the RGB to HSL conversion formula is fairly straightforward and requires only a few lines of code.

For clarity, all **input parameters** are expected to be in the range of [0, 255], while the **resulting values** are in the range of H: [0, 360], S: [0, 100], L: [0, 100].

const rgbToHsl = (r, g, b) => { r /= 255; g /= 255; b /= 255; const l = Math.max(r, g, b); const s = l - Math.min(r, g, b); const h = s ? l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s : 0; return [ 60 * h < 0 ? 60 * h + 360 : 60 * h, 100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0), (100 * (2 * l - s)) / 2, ]; }; rgbToHsl(45, 23, 11); // [21.17647, 60.71428, 10.98039]

## HSL to RGB

Similarly, converting from HSL to RGB requires implementing the HSL to RGB conversion formula. The **input parameters** are expected to be in the range of H: [0, 360], S: [0, 100], L: [0, 100], while the range of all **output values** is [0, 255].

const hslToRgb = (h, s, l) => { s /= 100; l /= 100; const k = n => (n + h / 30) % 12; const a = s * Math.min(l, 1 - l); const f = n => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1))); return [255 * f(0), 255 * f(8), 255 * f(4)]; }; hslToRgb(13, 100, 11); // [56.1, 12.155, 0]

## RGB to HSB

Much like HSL, HSB is another color format that can be derived from RGB. The RGB to HSB conversion formula is equally complex, but can be implemented in a few lines of code.

The range of all **input parameters** is [0, 255], while the range of the **resulting values** is H: [0, 360], S: [0, 100], B: [0, 100].

const rgbToHsb = (r, g, b) => { r /= 255; g /= 255; b /= 255; const v = Math.max(r, g, b), n = v - Math.min(r, g, b); const h = n === 0 ? 0 : n && v === r ? (g - b) / n : v === g ? 2 + (b - r) / n : 4 + (r - g) / n; return [60 * (h < 0 ? h + 6 : h), v && (n / v) * 100, v * 100]; }; rgbToHsb(252, 111, 48); // [18.529411764705856, 80.95238095238095, 98.82352941176471]

## HSB to RGB

Converting from HSB to RGB is equally straightforward, and requires implementing the HSB to RGB conversion formula. The range of the **input parameters** is H: [0, 360], S: [0, 100], B: [0, 100], while the range of all **output values** is [0, 255].

const hsbToRgb = (h, s, b) => { s /= 100; b /= 100; const k = (n) => (n + h / 60) % 6; const f = (n) => b * (1 - s * Math.max(0, Math.min(k(n), 4 - k(n), 1))); return [255 * f(5), 255 * f(3), 255 * f(1)]; }; hsbToRgb(18, 81, 99); // [252.45, 109.31084999999996, 47.965499999999984]

## HSL to HSB

Converting from HSL to HSB is a matter of **scaling the saturation and lightness** values to match the brightness value. This can be done using a simple formula, where the saturation is multiplied by the minimum of the lightness and 1 minus the lightness, and the lightness is added to the result.

The range of all **input parameters** is H: [0, 360], S: [0, 100], L: [0, 100], while the range of all **output values** is H: [0, 360], S: [0, 100], B: [0, 100].

const hslToHsb = (h, s, l) => { const b = l + (s / 100) * Math.min(l, 100 - l); s = b === 0 ? 0 : 2 * (1 - l / b) * 100; return [h, s, b]; }; hslToHsb(13, 100, 11); // [13, 100, 22]

## HSB to HSL

Converting from HSB to HSL is equally straightforward, and requires implementing the HSB to HSL conversion formula, which is the inverse of the HSL to HSB formula.

The range of the **input parameters** is H: [0, 360], S: [0, 100], B: [0, 100], while the range of all **output values** is H: [0, 360], S: [0, 100], L: [0, 100].

const hsbToHsl = (h, s, b) => { const l = (b / 100) * (100 - s / 2); s = l === 0 || l === 1 ? 0 : ((b - l) / Math.min(l, 100 - l)) * 100; return [h, s, l]; }; hsbToHsl(13, 100, 22); // [13, 100, 11]