4

How to efficiently get color of element which has no background, but one of his parent has? For example this is 3 levels depth set:

enter image description here

  • TOP1 is red
  • TOP2 is green
  • TOP3 doesn't have a background color defined, yet it is green.

I have no problem writing a function to iretate through parents and find backgroundColor property but I believe it's not really reliable and cross browserly would suck.

UPDATE

I may want to clarify why I want such a thing.

One of my cases: I am building sticky header for a table which will clone the first set of columns of a table and stick them(position: fixed) when user scrolls very wide table. So they can see the columns they are viewing.

Sometimes table has styles associated with it and columns have colors which may be inherited from table, it's container or actually anywhere. That's why I insist on using JavaScript solution on this.

lukas.pukenis
  • 13,057
  • 12
  • 47
  • 81
  • Have a look at [`window.getComputedStyle`](https://developer.mozilla.org/en-US/docs/Web/API/window.getComputedStyle). But it's not supported in older IE versions. – Felix Kling Jun 10 '13 at 10:59
  • @FelixKling - I believe he will need something more than that to account for cases where the innermost element's background is defined as transparent. – techfoobar Jun 10 '13 at 11:00
  • Are you sure you **want** to find third element's background color? Usually problems like these smell of some kind of hacks, where in reality you need to do some code refactoring to save that colour-status in some separate data structure rather than CSS style. – bezmax Jun 10 '13 at 11:03
  • @techfoobar: Oh, I somehow thought that `background-color` is inherited, but it doesn't seem to be the case :-/ – Felix Kling Jun 10 '13 at 11:07
  • Allready discussed here http://stackoverflow.com/questions/4259815/how-do-i-detect-the-inherited-background-color-of-an-element-using-jquery-js – Rick Jun 10 '13 at 11:08
  • getComputedStyles proved to be ineffective in this case. – lukas.pukenis Jun 10 '13 at 11:57
  • @Max, that may be the case, please see updated question. – lukas.pukenis Jun 10 '13 at 11:57

1 Answers1

4

There is no way to calculate the background of TOP3. If its background is not set, it is transparent. As such, it has the color of whatever is below it.

Example:

<div style="background: red; width: 100px; height: 100px">
  TOP1
  <div style="background: green; width: 80px; height: 80px">
    TOP2
    <div style="width: 60px; height: 100px; border: solid 1px yellow">
      TOP3
    </div>
  </div>
</div>

Preview:

Here, TOP3 is half green, half white. No CSS value can tell you this.

Community
  • 1
  • 1
Athari
  • 33,702
  • 16
  • 105
  • 146
  • Lets consider that parent is always bigger than child :) – lukas.pukenis Jun 10 '13 at 11:06
  • 1
    @lukas.pukenis Also let's consider positioning of all elements on the page is not relative, and z-order of elements is never changed, and margins are never negative etc. Such "let's consider" statements make any solution unreliable. If you know exact contraints, you can write whatever suits your needs. In this case, it's probably iterating through parents. – Athari Jun 10 '13 at 11:13
  • 2
    @Athari - I'd say its incorrect to say that there is no way at all. We can iterate through the elements found using elementFromPoint(), each time pushing what we hit to the bottom (with zIndex) till we hit something with a defined background thats not transparent. The question is whether *this* way is worth the trouble. – techfoobar Jun 10 '13 at 11:18
  • @Athari, no need to be offended. I was just thinking about most generic case. Negative margins, unordered z indexes, etc. can be left behind:) – lukas.pukenis Jun 10 '13 at 11:18
  • @techfoobar yes, exactly, I would like to know if it's worth the trouble or there's already a simple method to do so. – lukas.pukenis Jun 10 '13 at 11:18
  • @lukas.pukenis - I can't think of any simpler method if you need to account for all the cases (overlapping children, bigger children etc..). If you can assume *smaller fully contained children and larger parents* always - then you can simply iterate using `.parentNode`, till you hit something whose computed style for `background-color` is defined and not `transparent`. – techfoobar Jun 10 '13 at 11:26
  • @techfoobar The problem is formulated as "how to get element *color*". As you can see in my example, it's not color, but *colors*. Also, there's a further limitation in the question: "How to *efficiently* get color of element". Iterating with `elementFromPoint` for every pixel (!) of the element is obviously inefficient and impractical, so it does not satisfy the requirements. – Athari Jun 10 '13 at 11:47
  • @lukas.pukenis I'm not offfended. English isn't my native language, so it's sometimes hard for me to judge how harsh or nice my words sound. – Athari Jun 10 '13 at 11:49
  • @Athari - Yes iterating through all the x,y points will be extremely inefficient. I meant one point; like say, the center point, or say where the user clicked for example. – techfoobar Jun 10 '13 at 11:56
  • @Athari, english is my second language too so I may not be very clear :) – lukas.pukenis Jun 10 '13 at 11:56