20

I get color value with jQuery with .css('color'), and then I know color that it should be.

How can I compare color value that I get from jQuery with for example black color value?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
newbie
  • 24,286
  • 80
  • 201
  • 301
  • What do you want to compare? Brightness, hue, saturation? What's your goal? – Tatu Ulmanen Mar 04 '10 at 08:13
  • I need to know if text field has any real data. because now it has label on it in different color than when user has actually inputed something ... – newbie Mar 04 '10 at 09:04

7 Answers7

21

Here is an approach that should work on all browsers using JQuery:

  1. Create a hidden div <div id="dummy" style="display:none;"></div> on your HTML page. (Creating the dummy element dynamically with JQuery does not work for named colors)
  2. Set the color of the dummy element to the expected color, i.e. $('#dummy').css('color','black');
  3. Compare the color of the dummy element with the element you want to check

i.e.

if($('#element').css('color') === $('#dummy').css('color')) {
  //do something
}
Mike
  • 3,855
  • 5
  • 30
  • 39
  • 1
    This should be the correct answer. It's the only way where you can be confident that something like #c0cc00 and RGB(192, 204, 0) will compare. – Ed Bayiates Aug 14 '12 at 00:46
  • I don't think this is reliable either. In latest Chrome my dummy div returned 'white' but the element I compared it to returned 'rgb(255,255,255)' – Daniel Howard Mar 29 '16 at 19:40
  • Which operating system are you on? Do you have example code for what you did? – Mike Mar 29 '16 at 21:03
  • Some browsers give it back to you in the format you gave it to them. (Not many, these days, but...) – T.J. Crowder Jul 17 '17 at 16:51
  • After 5-6 hours I am so glad I found this. You'd think they'd have found a better solution by now. Major kudos to you man, I wish I could upvote twice! – madprogramer Jun 26 '18 at 16:14
  • @DanielHoward For Chrome, it makes a difference whether the dummy element is attached to the rendered DOM. If detached, `.css()` returns the raw style value string, if attached, it is converted to `rgb()`. – ccprog Jan 30 '19 at 16:30
17

What about...

if ($('#element').css('color') == 'rgb(0, 0, 0)')
{
    // do something
}

Replace 0, 0, 0 with the red, green and blue values of the colour value you want to compare.

.css() jQuery API

Andy Shellam
  • 15,403
  • 1
  • 27
  • 41
  • 3
    Note that this won't always work for Internet Explorer, as it returns the original value. So it could be anything from a 3 or 6 digit hexadecimal value to a named color. – Bruce van der Kooij Mar 15 '10 at 08:44
  • 1
    Yeah I wasn't sure on that, but I thought jQuery abstracted out the browser differences? – Andy Shellam Mar 15 '10 at 09:30
  • 3
    Isn't there like more of implementation independent solution for this? Even a slight change in spaces between RGB values would mess up this equality, let alone hex presentation or even simple word presentations like white or black. Anyone an idea? – Gerard May 04 '12 at 18:11
5

I had a similar problem where I had to toggle the bgnd color of an element. I solved it like this:

var color_one = "#FFA500";
var color_two = "#FFFF00";

function toggle_color(elem){
    var bgcolor = elem.css("background-color");
    elem.css("background-color", color_one);     // try new color
    if(bgcolor == elem.css("background-color"))  // check if color changed
        elem.css("background-color", color_two); // if here means our color was color_one
}
vjorjo
  • 51
  • 1
  • 2
  • I like this one, although I still think to be robust it's better to use a global variable to track the state.. so going to do that on my current project. Checking the color is easier, but too many chances for bugs. – eselk Nov 28 '12 at 17:11
  • Nice one, but it doesn't work with CSS3 transitions, good one though. I'll resort to trying to convert color values to a constant values. – Lzh Sep 11 '13 at 17:52
3

Here is my implementation of Mike's answer, in one function.

function compareColors(left, right) {
    // Create a dummy element to assign colors to.
    var dummy = $('<div/>');

    // Set the color to the left color value, and read it back.
    $(dummy).css('color', left);
    var adjustedLeft = $(dummy).css('color');

    // Set the color to the right color value, and read it back.
    $(dummy).css('color', right);
    var adjustedRight = $(dummy).css('color');

    // Both colors are now adjusted to use the browser's internal format,
    // so we can compare them directly.
    return adjustedLeft == adjustedRight;
}

You don't need to actually add the elements to the DOM for this to work. Tested in IE8, IE10, FF, Chrome, Safari.

Katie Kilian
  • 6,815
  • 5
  • 41
  • 64
2

CSS Colors can appear in many formats - rgb, rgba, #hex, hardly supported #hexalpha, infamous named colors, and the special transparent. To compare any color to any color you need to normalize them first. The colorValues function found here (gist) or here (SO answer will always give you [r,g,b,a] array of numeric values.
Then you can compare them like this:

var sameColor = colorValues(color1).join(',') === colorValues(color2).join(',');

colorValues function

// return array of [r,g,b,a] from any valid color. if failed returns undefined
function colorValues(color)
{
    if (color === '')
        return;
    if (color.toLowerCase() === 'transparent')
        return [0, 0, 0, 0];
    if (color[0] === '#')
    {
        if (color.length < 7)
        {
            // convert #RGB and #RGBA to #RRGGBB and #RRGGBBAA
            color = '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3] + (color.length > 4 ? color[4] + color[4] : '');
        }
        return [parseInt(color.substr(1, 2), 16),
            parseInt(color.substr(3, 2), 16),
            parseInt(color.substr(5, 2), 16),
            color.length > 7 ? parseInt(color.substr(7, 2), 16)/255 : 1];
    }
    if (color.indexOf('rgb') === -1)
    {
        // convert named colors
        var temp_elem = document.body.appendChild(document.createElement('fictum')); // intentionally use unknown tag to lower chances of css rule override with !important
        var flag = 'rgb(1, 2, 3)'; // this flag tested on chrome 59, ff 53, ie9, ie10, ie11, edge 14
        temp_elem.style.color = flag;
        if (temp_elem.style.color !== flag)
            return; // color set failed - some monstrous css rule is probably taking over the color of our object
        temp_elem.style.color = color;
        if (temp_elem.style.color === flag || temp_elem.style.color === '')
            return; // color parse failed
        color = getComputedStyle(temp_elem).color;
        document.body.removeChild(temp_elem);
    }
    if (color.indexOf('rgb') === 0)
    {
        if (color.indexOf('rgba') === -1)
            color += ',1'; // convert 'rgb(R,G,B)' to 'rgb(R,G,B)A' which looks awful but will pass the regxep below
        return color.match(/[\.\d]+/g).map(function (a)
        {
            return +a
        });
    }
}
oriadam
  • 7,747
  • 2
  • 50
  • 48
0

Actually I tried Charlie Kilian's answer. For some reason it didn't work when you try to set .css('color') with and 'rgb(0,0,0)' value.

I don't know why. Worked perfectly in the console. Maybe it was because my comparing function is in a javascript object and its some kind of a context issue or a reference problem. Either way finally I got frustrated and wrote my own function that will compare two colors regardless of the formats and does not create any elements or rely on jQuery. The function takes both HEX and RGB values.

It can probably be optimized but I really don't have the time right now. Hope this helps someone its pure javascript.

var compareColors= function (left, right) {
       var l= parseColor(left);
        var r=parseColor(right);
        if(l !=null && r!=null){
           return l.r == r.r && l.g == r.g && l.b == r.b;
        }else{
            return false;
        }
        function parseColor(color){
           if(color.length==6 || color.length==7){
                //hex color
               return {
                    r:hexToR(color),
                    g:hexToG(color),
                    b:hexToB(color)
                }
            }else if(color.toLowerCase().indexOf('rgb')>-1){
              var arr
                var re = /\s*[0-9]{1,3}\s*,\s*[0-9]{1,3}\s*,\s*[0-9]{1,3}\s*/gmi;
                var m;

                if ((m = re.exec(color)) !== null) {
                    if (m.index === re.lastIndex) {
                        re.lastIndex++;
                    }
                    // View your result using the m-variable.
                    // eg m[0] etc.
                    arr = m[0].split(',');
                    return {
                        r: parseInt(arr[0].trim()),
                        g: parseInt(arr[1].trim()),
                        b: parseInt(arr[2].trim())
                    }
                }else{
                  return null;
                }

            } else{
                return null;
            }
            function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
            function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
            function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
            function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
        }
    }

These following functions I took from www.javascripter.net

            function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
            function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
            function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
            function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
Daniel Doinov
  • 289
  • 3
  • 4
0

Modified from Katie Kilian's but without requiring jQuery

<div id="dummy"></div>
function compareColors(left, right) {
    // Create a dummy element to assign colors to.
    document.getElementById('dummy').style.background = left;
    var adjustedLeft = document.getElementById('dummy').style.background;

    // Set the color to the right color value, and read it back.
    document.getElementById('dummy').style.background = right;
    var adjustedRight = document.getElementById('dummy').style.background;

    // Both colors are now adjusted to use the browser's internal format,
    // so we can compare them directly.
    return adjustedLeft == adjustedRight;
}
MerryDan
  • 41
  • 3