5

Is it possible to see the inherited background color of a div?

How can I get the color that an html element inherits? By default elements are transparent. So, when a div is placed somewhere it will not show up in the render (but if the background color of that div is red it will be immediately visible). If there is no explicit background color, how can I find the implicit one?

Here is some example code. There is a div which is 1px by 1px in the top left of a picture of the Eiffel Tower. What is the background color of that div?

<html>
<body style="margin: 0px;">
<img src="http://www.eiffel-tower.us/Eiffel-Tower-Images/eiffel-tower-landmark-4.jpg">
<div style="position: absolute;top: 0px; left: 0px; width: 1px; height: 1px;z-index:1">
</div>
</body>
</html>
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • possible duplicate: http://stackoverflow.com/questions/5000108/how-can-i-tell-if-a-particular-css-property-is-inherited-with-jquery – Ram Jul 18 '12 at 18:17
  • how do you want to find it?, using javascript, or css or... – dezman Jul 18 '12 at 18:17
  • @watson - By any means possible. – Travis J Jul 18 '12 at 18:17
  • @Raminson - I do not believe that is a duplicate. Let me explain, I am looking for the color that is at the location of the div, it does not necessarily mean that there was an explicit color defined as a property there. – Travis J Jul 18 '12 at 18:18

5 Answers5

5

The method everyone will recommend, which sadly won't work in all cases..

You could traverse up the node-tree using the elements parent-property, checking if there is any element that has an explicit background-color.

The problem with this approach is that elements set to reside outside of their parent (using for example position:relative with the appropriate sibling values) can't be identified.


Any portable and 100% working solution to the problem?

The only portable way I can think of that will always yield the correct result is to find the (x,y) of where your element is in the browser.

Then iterate over all elements to see if any elements (x,y) results in that it's behind the needle-element and then check whether this element has a background-color property or not.

This is guaranteed to work, but will have a very hard impact on performance. If you are sure of the fact that an element isn't going to float itself outside of the bounds of it's true parent use the first method described.

If you'd like this method to work for elements which have an image as background-property you could load the said image onto a canvas and read the value of the pixel you'd like, though that will make the already performance sucking operation even more sucking, but it will work.

Also;

  • what if an element is floating above more than one element?
  • which color should be returned in a function implementing what you are describing?
  • The color shining through in the center of your needle-element, or maybe in the top left corner?

Element floating over 4 different elements, which is the elements background color?

floating div over 4 divs

nobody knows..

Community
  • 1
  • 1
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
  • What if there is no color property set? – Travis J Jul 18 '12 at 18:19
  • I am more concerned with what the color is if there was no property setting the color at any point under the "needle". – Travis J Jul 18 '12 at 18:28
  • You shouldn't be.. you should be concerned by the fact that one single element could have more than one N elements behind itself it set to float on top of elements, that's a better reason to be honest. – Filip Roséen - refp Jul 18 '12 at 18:29
  • In response to your edits: assume the size of the div is 1px by 1px. – Travis J Jul 18 '12 at 18:32
  • Then it's clear how to get the real color which is shining through by using what's described in section *"Any portable and 100% working solution to the problem?"* – Filip Roséen - refp Jul 18 '12 at 18:36
  • "This is guaranteed to work", and what if the color shining through is from an image? – Travis J Jul 18 '12 at 18:37
  • @TravisJ I'm not sure what you are trying to do, your question states that you are looking for the *background-color* property, if you aren't then the question is poorly written, and it's guaranteed to work with this description, as stated by this quote from my post *"then check whether this element has a background-color property or not"*. – Filip Roséen - refp Jul 18 '12 at 18:40
  • 1
    @TravisJ if the background property is actually an image you could load the image onto a *canvas* and read it pixel by pixel, I'll add this to my post. – Filip Roséen - refp Jul 18 '12 at 18:42
  • I clearly stated in my question: "If there is no explicit background color". I am sorry if that was not clear enough. – Travis J Jul 18 '12 at 18:42
  • @TravisJ by reading the other answers to this question apparently I'm not the only one who "misunderstood" what you were asking, also; *"if there is no explicit background color"* is implied to refer to the needle element with **transparent** background. – Filip Roséen - refp Jul 18 '12 at 18:44
  • @TravisJ if I were you I'd accept an answer in this thread (I think this one is the best so far, but that could change), try implementing it on my own, if trouble comes along start a new question where you ask for help and the community of stackoverflow can walk through the code together. – Filip Roséen - refp Jul 18 '12 at 18:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14092/discussion-between-refp-and-travis-j) – Filip Roséen - refp Jul 18 '12 at 18:48
4

Well, you could try something like this:

window.getComputedStyle = window.getComputedStyle || function(x) {return x.currentStyle;}
function getActualBackgroundColor(elem) {
    while(elem && window.getComputedStyle(elem).backgroundColor == "transparent")
        elem = elem.parentNode;
    return elem ? window.getComputedStyle(elem).backgroundColor : "transparent";
}

However, bear in mind that this will only work reliably for statically-positioned elements (ie. not position: absolute/relative/fixed) that are not floated and whose parents do not have background images.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
2

If the div inherited a background color from a parent element you would actually see it in the div. That's the beauty of cascading style sheets ;-)

So in order to find the implicit background color you have to move up the DOM tree until you find the parent element with a background color set.

This is really easy to do with e.g. Firebug for Firefox or the developer tools for Chrome, etc.

Horen
  • 11,184
  • 11
  • 71
  • 113
  • What if the color showing through was not from a background-color property? – Travis J Jul 18 '12 at 18:17
  • well that could mean you have a div on top of e.g. an image with thousands of different colors. there is no way that i know of to actually get the color of those pixels automatically with javascript. correct me if i'm wrong – Horen Jul 18 '12 at 18:21
  • What if the div was only 1px by 1px? – Travis J Jul 18 '12 at 18:21
  • i don't think that's possible. the only colors you can pull directly are css properties. and then you need to know exactly where your div is positioned. the only (automated) workaround i can think of is taking a screenshot and comparing the color at the position with the position of the div. that would be an aweful amount of work though and could be very problematic with different browser rendering... – Horen Jul 18 '12 at 18:25
  • Well I do not think it is possible very easily that is for sure. Perhaps with a detection method for the type of element that was beneath the element an approach to then determine the color could be used. I believe in css you can map part of images based on position to smaller images such as jquery.ui does. – Travis J Jul 18 '12 at 18:36
2

What you're really doing here is taking a 1x1 screenshot of part of the webpage. Try this question: https://stackoverflow.com/questions/7618368/how-to-capture-the-screen-using-javascript

The conclusion appears to be that (barring special extensions, plugins etc.) the way to do it is with html2canvas: Using HTML5/Canvas/JavaScript to take screenshots

Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366
1

You can recursively define a function that passes a jQuery object which checks for a background property.

function get_inherited_bg(jquery_object) {
    if (jquery_object.css("background") != "rgba(0, 0, 0, 0) none repeat scroll 0% 0%") {
        return jquery_object.css("background");
    }
    return get_inherited_bg(jquery_object.parent());
}

Enjoy and good luck!

Daniel Li
  • 14,976
  • 6
  • 43
  • 60