getComputedStyle('background-color') returns transparent, does not inherit ancestor's

1.7k Views Asked by At

getComputedStyle is supposed to return the final computed CSS property value. But for background-color, all browsers return transparent (or rgba(x,x,x,0)) instead of computing in inherited value from ancestors.

The only time the method works is if the element has a background color specified directly (even if through its class, but not through parent's definifions). But that makes getComputedStyle useless, it should take in account all ancestor's definitions.

The method works fine for other things like color as shown in the fiddle.

How can i get the effective background color of an element in JS instead of every element telling me it is transparent?

let para = document.querySelector('p');
let compStyles = window.getComputedStyle(para);
para.textContent = 'Incorrect background-color: ' + compStyles.getPropertyValue('background-color') + ', but font color is correct: ' + compStyles.getPropertyValue('color');
/* no colors are specified for p */
p {
  width: 400px;
  margin: 0 auto;
  padding: 20px;
  line-height: 2;
  font-size: 2rem;
  font-family: sans-serif;
  text-align: center;
}

/* this is the important part, only color gets inherited, not background-color */
div {
  background-color: purple;
  color: lightblue;
}
<!-- Original example taken from MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle -->

<div>
  <p>Hello</p>
</div>

If it helps, the X question is How do i compute color luminosity difference between font color and background for each element in a page in an userscript ;) That getComputedStyle does not work makes it not doable imho. But this question should be interesting on its own.

3

There are 3 best solutions below

2
On BEST ANSWER

It's because background-color property is not inherited by the children elements (unlike the color property).

You can read more at: https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance

0
On

This is the correct result, because background color is not inherited. From MDN:

Initial value transparent
Applies to all elements. It also applies to ::first-letter and ::first-line.
Inherited no
Media visual
Computed value computed color
Animation type a color
Canonical order the unique non-ambiguous order defined by the formal grammar

1
On

To piggyback on other answers. Here's a working example using inherited css.

/* no colors are specified for p */
p {
  width: 400px;
  margin: 0 auto;
  padding: 20px;
  line-height: 2;
  font-size: 2rem;
  font-family: sans-serif;
  text-align: center;
  background-color: inherit;  /* I added this */
}

/* this is the important part, only color gets inherited, not background-color */
div {
  background-color: purple;
  color: lightblue;
}

https://jsfiddle.net/meq6x5ay/