Using jQuery (or just JavaScript), how do I detect the inherited background-color of an element?
For example:
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!");
}
});
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.
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'
.
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>
#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.
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');