Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox issue with currentStyle vs getComputedStyle

I am trying to get the width of an element according to it's CSS rules The problem is that "getComputedStyle" returns a pixel value instead of "auto" for an element with no CSS width value set. In Opera, "elem.currentStyle['width']" returns "auto", but in firefox, it must use "getComputedStyle" which returns something like "1149px".

It is vital for me to know what the actual CSS rule is. Is there some way of doing this besides besides getComputedStyle? The Firefox MDN makes it clear "getComputedStyle" is not the way to go, but I cannot find any documentation for a Firefox equivalent to "currentStyle".

If you want to know, my end goal is to find the largest static-width element on the page. If I cannot read stylesheet values - only rendered/computed values - then how can I achieve this?

like image 718
rburgenson Avatar asked Aug 29 '11 04:08

rburgenson


2 Answers

If you start with an element, there is no way to know which stylesheet rules applied to it. getComputedStyle() merely gives you the effective style value and currentStyle isn't much different even though it happens to give you the result you expect in this particular scenario and this particular browser.

What you probably need to do is to go through the stylesheets instead. Along the lines of:

for (var i = 0; i < document.styleSheets.length; i++)
{
  var styleSheet = document.styleSheets[i];
  for (var j = 0; j < styleSheet.cssRules.length; j++)
  {
    var rule = styleSheet.cssRules[j];
    if (rule.type == 1)  // STYLE_RULE
    {
      // Do something with rule.style.width
    }
  }
}

If you then need to locate elements matching that rule you can use document.querySelectorAll() with rule.selectorText. The remaining problem is that multiple style rules might apply to the same element and the specificity of the rule needs to be calculated. Not sure how much this is a problem for you however.

Additional documentation:

  • CSSStyleSheet
  • CSSStyleRule
like image 161
Wladimir Palant Avatar answered Sep 20 '22 12:09

Wladimir Palant


Unfortunately, as far as I know there is no realistic way to achieve this.

Edit: The above answer looping through the style sheets is your best bet. I originally thought of accessing the stylesheets but did not think of using querySelectorAll. Hats off to Wladimir for a genius solution.

--

The only solution I could think of is for the elements you're setting a width to, also set some other uncommonly used style to something that won't really affect anything, so you can test for that.

div {
    width: 35px;
    min-width: 1px; /* the flag */
    }

So then when looking for the elements with a specified width, you can look for [ComputedStyle].minWidth == '1px' first.

Quite a hacky solution but it'll get the job done.

You could also set a random class name to the elements that have a set width, then all you would have to do is query for the elements with that class name. Although it's not a very dynamic solution.

like image 1
Ben Avatar answered Sep 23 '22 12:09

Ben