First ValueTake the first number, 220, and divide by 16. 220 / 16 = 13.75, which means that the first digit of the 6-digit hex color code is 13, or D. Take the remainder of the first digit, 0.75, and multiply by 16. 0.75 (16) = 12, which means that the second digit of the 6-digit hex color code is 12, or C.
Use this clean one-line function with both rgb
and rgba
support:
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
Much time has passed since I originally answered this question. Then cool ECMAScript 5 and 2015+ features become largely available on browsers, like arrow functions, Array.map, String.padStart and template strings. So now it's possible to write an one-liner rgb2hex
:
const rgb2hex = (rgb) => `#${rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(n => parseInt(n, 10).toString(16).padStart(2, '0')).join('')}`
// Use as you wish...
console.log(rgb2hex('rgb(0,0,0)'))
console.log(rgb2hex('rgb(255, 255, 255)'))
console.log(rgb2hex('rgb(255,0,0)'))
console.log(rgb2hex('rgb(38, 170, 90)'))
Basically, we use a regular expression to get each digit inside the rgb
string, slice(1)
to get only the digits (the first result of match
is the full string itself), map
to iterate through each digit, each iteration converting to Number
with parseInt
, then back to an hexadecimal String
(through a base-16 conversion), adding zero if needed via padStart
. Finally, just join
each converted/adjusted digit to a unique String
starting with '#'
.
Of course, we could extend it without much effort as an one-liner rgba2hex
:
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
// Now it doesn't matter if 'rgb' or 'rgba'...
console.log(rgba2hex('rgb(0,0,0)'))
console.log(rgba2hex('rgb(255, 255, 255)'))
console.log(rgba2hex('rgb(255,0,0)'))
console.log(rgba2hex('rgb(38, 170, 90)'))
console.log(rgba2hex('rgba(255, 0, 0, 0.5)'))
console.log(rgba2hex('rgba(0,255,0,1)'))
console.log(rgba2hex('rgba(127,127,127,0.25)'))
And that's it. But if you want to dive deep in the old school JavaScript world, keep reading.
Here is the cleaner solution I wrote based on @Matt suggestion:
function rgb2hex(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
Some browsers already returns colors as hexadecimal (as of Internet Explorer 8 and below). If you need to deal with those cases, just append a condition inside the function, like @gfrobenius suggested:
function rgb2hex(rgb) {
if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb;
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
If you're using jQuery and want a more complete approach, you can use CSS Hooks available since jQuery 1.4.3, as I showed when answering this question: Can I force jQuery.css("backgroundColor") returns on hexadecimal format?
var hexDigits = new Array
("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
//Function to convert rgb color to hex format
function rgb2hex(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
function hex(x) {
return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
}
(Source)
Most browsers seem to return the RGB value when using:
$('#selector').css('backgroundColor');
Only I.E (only 6 tested so far) returns the Hex value.
To avoid error messages in I.E, you could wrap the function in an if statement:
function rgb2hex(rgb) {
if ( rgb.search("rgb") == -1 ) {
return rgb;
} else {
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
}
Updated @ErickPetru for rgba compatibility:
function rgb2hex(rgb) {
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
I updated the regex to match the alpha value if defined, but not use it.
Here's an ES6 one liner that doesn't use jQuery:
var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => parseInt(color).toString(16).padStart(2, '0')).join('');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With