How do I detect the inherited background-color of an element using jQuery/JS?
Asked Answered
S

6

15

Using jQuery (or just JavaScript), how do I detect the inherited background-color of an element?

For example:

<div style="background-color: red">
    <p id="target">I'd like to know that the background-color here is red</p>
</div>

However:

$('#target').css('background-color') == rgba(0,0,0,0)

and

$('#target').css('backgroundColor') == rgba(0,0,0,0)

I'm asking for a general solution. $('#target').parent().css('background-color') would work in this instance, but not all.

Soerabaja answered 23/11, 2010 at 19:11 Comment(0)
A
11

This could be accomplished by using the parent() in a loop until you reach the body tag:

I've set up a quick jsfiddle site with a little demo based on your code.

Edit: Good catch fudgey. After doing some testing it appears that IE7 will return 'transparent' instead of the rgba(0,0,0,0) value. Here's an updated link which I tested in IE7, Chrome 7, and Firefox 3.6.1.2. Another caveat with this approach: Chrome/Firefox will return rgb(255,0,0); IE returned 'red'.

Awhile answered 23/11, 2010 at 19:12 Comment(3)
David, Thank you for your code! This is the approach I'm looking at right now. I just find it hard to believe that there isn't a more direct and reliable way to determine this, and as another user pointed out, there is no guarantee that an element is positioned on top of its parent.Soerabaja
I was getting an alert of "transparent", try changing it to color !== 'transparent' - then I get an alert of rgb(255, 0, 0) - updated demo: jsfiddle.net/Mottie/Y4uDL/1Hollander
but what if background color is actually rgba(0, 0, 0, 0) and the parent is green?? Your solution won't workLithoid
E
10

You can make use of window.getComputedStyle() to get the inherited value.

Caveat: You must manually declare the inheritance in css or inline.

#target{
  background-color: inherit;
}

Working example:

let bgc = window.getComputedStyle($('#target')[0],null).getPropertyValue("background-color");
console.log(bgc);
#target{
  background-color: inherit;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="background-color: red">
    <p id="target">I'd like to know that the background-color here is red</p>
</div>
Eleanore answered 17/11, 2017 at 3:27 Comment(0)
G
4

#target has no background color to read because background-color is not inherited.

you could write some javascript that keeps climbing up the DOM tree to search for a background-color declaration until it finds one., but there's no guarantee that that will get you the background color of an element that actually contains your #target.

btw. the css() method gets computed styles, so its giving you the correct reading.

Grow answered 23/11, 2010 at 19:27 Comment(2)
You wrote this in as I was trying to figure out why getComputedStyle and currentStyle weren't working for background-colorSpherulite
Sebastian - Thank you for your answer! I may edit my question's wording, given what I've learned from your answer.Soerabaja
H
3

Here's the answer for people who hate browser inconsistency.

As explained, you need to test if this element has a transparent background, then if it does, walk through the DOM until you find a parent with background-color set - but that means testing whatever string each browser chooses to return.

Firefox, IE and others return transparent, Chrome/safari/webkit browsers etc return rgba(0, 0, 0, 0)... and I personally don't trust that there won't be some other exception out there somewhere, now or in the future.

If you don't like the idea of trusting a string given to you by a browser (and you shouldn't), you don't have to: just test against the background-color of an empty element.

Here's a JSBIN example of it in action. (to test on old IE, remove 'edit' from URL)


Usage: Plonk this code somewhere (it works as a jQuery plugin)...

(function($) {
  // Get this browser's take on no fill
  // Must be appended else Chrome etc return 'initial'
  var $temp = $('<div style="background:none;display:none;"/>').appendTo('body');
  var transparent = $temp.css('backgroundColor');
  $temp.remove();

jQuery.fn.bkgcolor = function( fallback ) {
    function test( $elem ) {
        if ( $elem.css('backgroundColor') == transparent ) {
          return !$elem.is('body') ? test( $elem.parent() ) : fallback || transparent ;
        } else {
          return $elem.css('backgroundColor');
        }
    }
    return test( $(this) );
};

})(jQuery);

...then you can get the 'inherited' background colour of any element like this:

var backgroundColor = $('#someelement').bkgcolor();

Or if you want a fallback to be applied instead of 'transparent' if no background-color is set here or anywhere behind this element (e.g. for matching overlays), send as an argument:

var backgroundColor = $('#someelement').bkgcolor('#ffffff');
Hesky answered 4/3, 2013 at 18:11 Comment(1)
It's 2021 and this is still the best answer, in my opinion. Currently, Firefox and Chrome both return "rgba(0, 0, 0, 0)", but there's no guarantee they will continue to do so. Important to note you will have to append the sample element to the body before trying to compute the background-color. After you've done your checks, you can simply remove it.Lieb
P
2

Hacky-Recursive answer

jQuery.fn.InheritedBackgroundColor = function(){    
   jQuery(this).parents().each( function(){
      var bc = jQuery(this).css("background-color");
      if( bc == "transparent" ){
         return jQuery(this).InheritedBackgroundColor();
      }
      else{
         return bc;
      }      
   });
}

$(document).ready(function(){
   if( $("#target").InheritedBackgroundColor() == rbga(255,0,0,0) ){
      alert("Win!");
   }
   else{
      alert("FAIL!");
   }

});
Pillion answered 23/11, 2010 at 19:34 Comment(0)
C
-1

Here's an elegant way of solving this problem (sorry, I prefer CoffeeScript). It starts from self, but you always can just use $el.parents().each ->.

findClosestBackgroundColor = ($el) ->
    background = 'white'
    $.merge($el, $el.parents()).each ->
      bg = $(this).css('background-color')
      if bg isnt 'transparent' and !/rgba/.test(bg)
        background = bg
        return false
    background

DEMO: Use coffeescript.org to compile this to javascript and run this in a console on any page that has jQuery included.

Claudy answered 21/5, 2015 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.