Using the following jQuery will get the RGB value of an element's background color:
$('#selector').css('backgroundColor');
Is there a way to get the hex value rather than the RGB?
Using the following jQuery will get the RGB value of an element's background color:
$('#selector').css('backgroundColor');
Is there a way to get the hex value rather than the RGB?
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)
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?
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 is a version that also checks for transparent, I needed this since my object was to insert the result into a style attribute, where the transparent version of a hex color is actually the word "transparent"..
function rgb2hex(rgb) {
if ( rgb.search("rgb") == -1 ) {
return rgb;
}
else if ( rgb == 'rgba(0, 0, 0, 0)' ) {
return 'transparent';
}
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]);
}
}
Function that returns background color of an element in hex.
function getBgColorHex(elem){
var color = elem.css('background-color')
var hex;
if(color.indexOf('#')>-1){
//for IE
hex = color;
} else {
var rgb = color.match(/\d+/g);
hex = '#'+ ('0' + parseInt(rgb[0], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2);
}
return hex;
}
usage example:
$('#div1').click(function(){
alert(getBgColorHex($(this));
}
Same answer like @Jim F answer but ES6 syntax , so, less instructions :
const rgb2hex = (rgb) => {
if (rgb.search("rgb") === -1) return rgb;
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
const hex = (x) => ("0" + parseInt(x).toString(16)).slice(-2);
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
};
Try
// c - color str e.g."rgb(12,233,43)", result color hex e.g. "#0ce92b"
let rgb2hex= c=> '#'+c.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``
// rgb - color str e.g."rgb(12,233,43)", result color hex e.g. "#0ce92b"
let rgb2hex= c=> '#'+c.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``
console.log(rgb2hex("rgb(12,233,43"));
color class taken from bootstrap color picker
// Color object
var Color = function(val) {
this.value = {
h: 1,
s: 1,
b: 1,
a: 1
};
this.setColor(val);
};
Color.prototype = {
constructor: Color,
//parse a string to HSB
setColor: function(val){
val = val.toLowerCase();
var that = this;
$.each( CPGlobal.stringParsers, function( i, parser ) {
var match = parser.re.exec( val ),
values = match && parser.parse( match ),
space = parser.space||'rgba';
if ( values ) {
if (space === 'hsla') {
that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
} else {
that.value = CPGlobal.RGBtoHSB.apply(null, values);
}
return false;
}
});
},
setHue: function(h) {
this.value.h = 1- h;
},
setSaturation: function(s) {
this.value.s = s;
},
setLightness: function(b) {
this.value.b = 1- b;
},
setAlpha: function(a) {
this.value.a = parseInt((1 - a)*100, 10)/100;
},
// HSBtoRGB from RaphaelJS
// https://github.com/DmitryBaranovskiy/raphael/
toRGB: function(h, s, b, a) {
if (!h) {
h = this.value.h;
s = this.value.s;
b = this.value.b;
}
h *= 360;
var R, G, B, X, C;
h = (h % 360) / 60;
C = b * s;
X = C * (1 - Math.abs(h % 2 - 1));
R = G = B = b - C;
h = ~~h;
R += [C, X, 0, 0, X, C][h];
G += [X, C, C, X, 0, 0][h];
B += [0, 0, X, C, C, X][h];
return {
r: Math.round(R*255),
g: Math.round(G*255),
b: Math.round(B*255),
a: a||this.value.a
};
},
toHex: function(h, s, b, a){
var rgb = this.toRGB(h, s, b, a);
return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
},
toHSL: function(h, s, b, a){
if (!h) {
h = this.value.h;
s = this.value.s;
b = this.value.b;
}
var H = h,
L = (2 - s) * b,
S = s * b;
if (L > 0 && L <= 1) {
S /= L;
} else {
S /= 2 - L;
}
L /= 2;
if (S > 1) {
S = 1;
}
return {
h: H,
s: S,
l: L,
a: a||this.value.a
};
}
};
how to use
var color = new Color("RGB(0,5,5)");
color.toHex()
I've created a function that uses readable basic functions and no reg-exps.
The function accepts color in hex, rgb or rgba CSS format and returns hex representation.
EDIT: there was a bug with parsing out rgba() format, fixed...
function getHexColor( color ){
//if color is already in hex, just return it...
if( color.indexOf('#') != -1 ) return color;
//leave only "R,G,B" :
color = color
.replace("rgba", "") //must go BEFORE rgb replace
.replace("rgb", "")
.replace("(", "")
.replace(")", "");
color = color.split(","); // get Array["R","G","B"]
// 0) add leading #
// 1) add leading zero, so we get 0XY or 0X
// 2) append leading zero with parsed out int value of R/G/B
// converted to HEX string representation
// 3) slice out 2 last chars (get last 2 chars) =>
// => we get XY from 0XY and 0X stays the same
return "#"
+ ( '0' + parseInt(color[0], 10).toString(16) ).slice(-2)
+ ( '0' + parseInt(color[1], 10).toString(16) ).slice(-2)
+ ( '0' + parseInt(color[2], 10).toString(16) ).slice(-2);
}
Just to add to @Justin's answer above..
it should be
var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => String("0" + parseInt(color).toString(16)).slice(-2)).join('');
As the above parse int functions truncates leading zeroes, thus produces incorrect color codes of 5 or 4 letters may be... i.e. for rgb(216, 160, 10) it produces #d8a0a while it should be #d8a00a.
Thanks
This one looks a bit nicer:
var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var r = parseInt(rgb[0], 10);
var g = parseInt(rgb[1], 10);
var b = parseInt(rgb[2], 10);
var hex = '#'+ r.toString(16) + g.toString(16) + b.toString(16);
a more succinct one-liner:
var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var hex = '#'+ Number(rgb[0]).toString(16) + Number(rgb[1]).toString(16) + Number(rgb[2]).toString(16);
forcing jQuery to always return hex:
$.cssHooks.backgroundColor = {
get: function(elem) {
if (elem.currentStyle)
var bg = elem.currentStyle["backgroundColor"];
else if (window.getComputedStyle) {
var bg = document.defaultView.getComputedStyle(elem,
null).getPropertyValue("background-color");
}
if (bg.search("rgb") == -1) {
return bg;
} else {
bg = bg.match(/\d+/g);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(bg[0]) + hex(bg[1]) + hex(bg[2]);
}
}
}
Here's a solution I found that does not throw scripting errors in IE: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx
Steven Pribilinskiy's answer drops leading zeroes, for example #ff0000 becomes #ff00.
A solution is to append a leading 0 and substring off the last 2 digits.
var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var hex = '#'+ String('0' + Number(rgb[0]).toString(16)).slice(-2) + String('0' + Number(rgb[1]).toString(16)).slice(-2) + String('0' + Number(rgb[2]).toString(16)).slice(-2);
Since the question was using JQuery, here’s a JQuery plugin based on Daniel Elliott’s code:
$.fn.cssAsHex = function(colorProp) {
var hexDigits = '0123456789abcdef';
function hex(x) {
return isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
};
// Convert RGB color to Hex format
function rgb2hex(rgb) {
var rgbRegex = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
return '#' + hex(rgbRegex[1]) + hex(rgbRegex[2]) + hex(rgbRegex[3]);
};
return rgb2hex(this.css(colorProp));
};
Use it like:
var hexBackgroundColor = $('#myElement').cssAsHex('background-color');
Here is my solution, also does touppercase by the use of an argument and checks for other possible white-spaces and capitalisation in the supplied string.
var a = "rgb(10, 128, 255)";
var b = "rgb( 10, 128, 255)";
var c = "rgb(10, 128, 255 )";
var d = "rgb ( 10, 128, 255 )";
var e = "RGB ( 10, 128, 255 )";
var f = "rgb(10,128,255)";
var g = "rgb(10, 128,)";
var rgbToHex = (function () {
var rx = /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
function pad(num) {
if (num.length === 1) {
num = "0" + num;
}
return num;
}
return function (rgb, uppercase) {
var rxArray = rgb.match(rx),
hex;
if (rxArray !== null) {
hex = pad(parseInt(rxArray[1], 10).toString(16)) + pad(parseInt(rxArray[2], 10).toString(16)) + pad(parseInt(rxArray[3], 10).toString(16));
if (uppercase === true) {
hex = hex.toUpperCase();
}
return hex;
}
return;
};
}());
console.log(rgbToHex(a));
console.log(rgbToHex(b, true));
console.log(rgbToHex(c));
console.log(rgbToHex(d));
console.log(rgbToHex(e));
console.log(rgbToHex(f));
console.log(rgbToHex(g));
On jsfiddle
Speed comparison on jsperf
A further improvement could be to trim()
the rgb
string
var rxArray = rgb.trim().match(rx),
I am using Jasmine protractor and I was getting errors like
- Expected [ 'rgba(255, 255, 255, 1)' ] to contain '#fff'.
Below function worked fine for me.
function RGBAToHexA(test:string) {
let sep = test.toString().indexOf(",") > -1 ? "," : " ";
const rgba = test.toString().substring(5).split(")")[0].split(sep);
console.log(rgba)
let r = (+rgba[0]).toString(16),
g = (+rgba[1]).toString(16),
b = (+rgba[2]).toString(16),
a = Math.round(+rgba[3] * 255).toString(16);
if (r.length == 1)
r = "0" + r;
if (g.length == 1)
g = "0" + g;
if (b.length == 1)
b = "0" + b;
if (a.length == 1)
a = "0" + a;
return "#" + r + g + b + a;
}
describe('Check CSS', function() {
it('should check css of login page', async function(){
browser.waitForAngularEnabled(true);
browser.actions().mouseMove(element(by.css('.btn-auth, .btn-auth:hover'))).perform(); // mouse hover on button
csspage.Loc_auth_btn.getCssValue('color').then(function(color){
console.log(RGBAToHexA(color))
expect( RGBAToHexA(color)).toContain(cssData.hoverauth.color);
})
To all the Functional Programming lovers, here is a somewhat functional approach :)
const getHexColor = (rgbValue) =>
rgbValue.replace("rgb(", "").replace(")", "").split(",")
.map(colorValue => (colorValue > 15 ? "0" : "") + colorValue.toString(16))
.reduce((acc, hexValue) => acc + hexValue, "#")
then use it like:
const testRGB = "rgb(13,23,12)"
getHexColor(testRGB)
full cases (rgb, rgba, transparent...etc) solution (coffeeScript)
rgb2hex: (rgb, transparentDefault=null)->
return null unless rgb
return rgb if rgb.indexOf('#') != -1
return transparentDefault || 'transparent' if rgb == 'rgba(0, 0, 0, 0)'
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
hex = (x)->
("0" + parseInt(x).toString(16)).slice(-2)
'#' + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3])