Converting to Pixels with javascript

Since the original getComputedStyle(..) function was posted in a previous blog entry, I'm not going to bother posting it again. Instead, I'll only post the updated version below.


if (!window.sstchur) { window.sstchur = {}; }
if (!sstchur.web) { sstchur.web = {}; }
if (!sstchur.web.xb) { sstchur.web.xb = {}; }

sstchur.web.xb.getComputedStyle = function(_elem, _style)
{
  var nonPixels = /(em|ex|pt|%)$/;

  var computedStyle;
  if (typeof _elem.currentStyle != 'undefined')
  {
    computedStyle = _elem.currentStyle;
    var val = computedStyle[_style];
    if (nonPixels.test(val))
      { return sstchur.web.xb.convertToPixels(val, _elem); }
  }
  else
    { computedStyle = document.defaultView.getComputedStyle(_elem, null); }

  return computedStyle[_style];
}

There aren't many changes to this function. The only thing required is to utilize our convertToPixels(..) function if we're in the if (typeof _elem.currentStyle != 'undefined') block. However, we don't want to do this unconditionally. It's perfectly feasible that we might want to retrieve a computed style that has nothing to do with units (a color value for example: #369 or something like that). In this case, we absolutely don't want to call convertToPixels(..) becuase it would fail (probably with a js error).

To avoid such a scenerio, we sipmly create a regular expression matching any string that ends with any of: 'em', 'ex', 'pt' or '%'. If the computed style ends with one of those units, then it's probably safe to utilize convertToPixels(..).

By taking advantage of the convertToPixels(..) function we just wrote, our sstchur.web.xb.getComputedStyle(..) is edging ever closer to the utopian dream of W3C compliance. It's still not perfect mind you. A perfect function would not only normalize all units to pixels, but also normalize all color values from hex codes, like #fff to rgb values, like rgb(255, 255, 255).

Still, just having our function return us a consisten unit across browsers is a major step in the right direction.

Comments welcome.

7 thoughts on “Converting to Pixels with javascript”

  1. This is perfect: I'm writing a image replacement solution that will benefit hugely from this. Thanks for sharing it!

  2. This returns height of the element in pixels.
    In firefox 2.0.0.14 and IE 7.

    document.getElementById('div1').scrollHeight

    It seems to me that the browsers are implemented the way to complicate the things as much as possible. You must cheat all the time :-))

  3. Vlado,

    Thanks for the tip. I've only run across .scrollHeight once or twice and haven't really utilized it much. Do you know if it give the overall height of an element, including borders and padding? Or just the internal height of the element (minus borders and padding)?

    What does IE6 think of this property?

  4. if _context is optional and units are percentual, function raise an error when calling convertToPixels('75%')
    in this line:
    _context = _context.parentNode || _context;

  5. great stuff! Now… How do I convert from pixels to percent? I have a div within a div, and I want to find the percent the inner div is of the outerdiv. I tried (slice/pie)*100; and then set the innerdiv to that percent, but sometimes it's off by a pixel.

  6. Joe:

    This is a little bit tricky because you have to consider the fact that when you specify a dimension as a percentage in CSS, it's a percentage of the parent's STYLE height (that is, its height as specified in CSS). Bear in mind that this could be rather different from its rendered height on screen.

    For instance, if you specify that an element have height: 400px, but then also give it 10px padding all around, and a 20px border all around, the total height (offsetHeight) will actually be 60px more (30px on top and bottom). However, that extra 60px doesn't come into play when calculating the height of some child element specified as a percentage.

    What you really want then is the style height of the outer element (that is, you need the height in pixels of the outer element as specified in the CSS). And to further complicate your life, that value might not be specified in px, and if you're in IE, then you'll need to convert it to px 🙂

    And you'll need the same value of the inner element. Probably, your favorite Javascript library has a way of getting the height (or width) of an element as specified in CSS (note that reading .style.height will not work if the height was not specified via .style.height or via an inline style attribute).

    I don't know how to do this in jQuery or Prototype or Dojo, but in Gimme (my library) it would look like:

    var innerElemHeight = parseInt(Gimme('#innerElem').get_style('height'));
    var outerElemHeight = parseInt(Gimme('#outerElem').get_style('height'));
    var pct = innerElemHeight / outerElemHeight;

    Hope this helps!

Leave a Reply

Your email address will not be published. Required fields are marked *