Retrieving CSS styles via JavaScript

posted in: css, javascript | 0

Unobstrusive JavaScript is getting popular. Scripts are used to enrich a page’s look while the HTML source code remains pretty clean. Examples are jQuery, script.aculo.us, and of course RUZEE.Borders ;-).

One important method is the retrieval of the current CSS style of a given HTML element. Let me show you my recent observations dealing with that issue.

First of all we need a reference to the element we want to get the CSS style for. In this example, we simply use getElementById().

var e=document.getElementById('someid');

Now there are two different ways for retrieving the current style of e. The standard way uses the getComputedStyle() method:

var cs=document.defaultView.getComputedStyle(e,null);

To get the background color of e, you can now call

var bg=cs.getPropertyValue('background-color');

That’s basically it and it works with all modern browsers (Firefox, Safari 2, Konqueror 3.5, Opera 9), except Internet Explorer. IE however has a different way for retrieving the style:

var bg=e.currentStyle['backgroundColor'];

As you can see, you have to specify the CSS property in the camel case notation. Apart from that, the IE way does the same as the standard way and it works with IEs>=5.0.

Here’s a working JavaScript which retrieves the current style with the techniques described:

// convert s to camel case
function rzCC(s){
  for(var exp=/-([a-z])/; exp.test(s); s=s.replace(exp,RegExp.$1.toUpperCase()));
  return s;
};

function rzGetStyle(e,a){
  var v=null;
  if(document.defaultView && document.defaultView.getComputedStyle){
    var cs=document.defaultView.getComputedStyle(e,null);
    if(cs && cs.getPropertyValue) v=cs.getPropertyValue(a);
  }
  if(!v && e.currentStyle) v=e.currentStyle[rzCC(a)];
  return v;
};

I’ve chosen the background-color property for a specific reason. Background colors are inherted from the parent element if they have not been specified for a child, e.g.

<div style="background:red">
  <div id="someid">
     Germany will beat Portugal!
  </div>
</div>

The methods above will return ‘transparent’ when called for the element with the ID someid, with two exceptions:

  • Safari will return “rgba(0, 0, 0, 0)”, which means transparent, because the forth value stands for the opacity which is 0.
  • Konqueror 3.5 will return “#000000” which is black and which is at the same time a known bug of Konqueror. I’ve tried to use getPropertyCSSValue, but that one is borked completely…

Now, if you want to retrieve the “real” background color of an element, you have to recursively move up the hierarchy until you find an element that doesn’t have a transparent background. You have to stop however at document.body and assume white as background color. Here’s the code:

function rzGetBg(e){
  var v=rzGetStyle(e,'background-color');
  while (!v || v=='transparent' || v=='#000000' || v=='rgba(0, 0, 0, 0)'){
    if(e==document.body) v='#fff'; else {
      e=e.parentNode;
      v=rzGetStyle(e,'background-color');
    }
  }
  return v;
};

The implication of Konqueror returning transparent as black is, that if you want to support Konqueror, a black background is not allowed on your web page. Using #010101, which is “almost black” is the best you can do…