getComputedStyle doesn't like humps

written by Tobie on November 21st, 2006 @ 10:01 PM

Accessing CSS styles via JavaScript is an obscure business. To access an element’s inline styles, the style property must be camelized.

For example, to access or modify the inline font-style of an element, the following syntax is needed: $(element).style.fontSize.

Camelizing generally consists in removing white spaces, dashes, underscore, etc. and capitalizing the following letter, producing these little humps which have evidently inspired whoever came up with this technique when baptizing it.

But who uses inline styles anyway?

True. It’s usually considered bad practice.

As inline styles have the highest precedence (i.e. they overrule whatever was previously set in a stylesheets), they are really usefull for DOM scripting. Effects libraries such as script.aculo.us rely on them heavily, but they are not really fit for anything else. Your styling should go in external CSS files.

And guess what: all modern browsers provide us with a way to access those too.

accessing styles applied from within the style tag or from external stylesheets

To find out what styling is applied to a given element, W3C compliant browser provide us with the getComputedStyle and getPropertyValue methods… while Internet Explorer uses it’s own proprietary currentStyle method.

And this is where things start to get complicated.

IE’s currentStyle method needs camelized arguments, getPropertyValue wants standard CSS style ones.

// in Internet Explorer:
element.currentStyle.fontSize

// in W3C compliant browsers (it's a bit more
// complicated; but don't worry about it too
// much, Prototype deals with it beautifully).
var css = document.defaultView.getComputedStyle(element, null);
css ? css.getPropertyValue('font-size') : null;

To add to this confusion, some W3C compliant browsers still return a correct value on quite a number of styles when passed a camelized string rather than a CSS one. Which can lure you (it lured me!) into thinking that getPropertyValue expects a camelized argument.

Well it doesn’t!


var css = document.defaultView.getComputedStyle(element, null);
value = css ? css.getPropertyValue('fontSize') : null;

will return zip, nothing, nada on elements whose font-size has been specified in an external stylesheet.

Prototype does it all for you as long as you do NOT camelize your argument.

For those of you who use Prototype’s great getStyle element method, Prototype deals with these discrepancies as long as getStyle is passed a normal, CSS like, non-camelized string.

$(element).getStyle('font-size') // this is correct. $(element).getStyle('fontSize') // this is WRONG!

On the other hand, when using setStyle you should be using camelized keys in your hash, as you are accessing the inline style properties (which, remember, are always camelized). Furthermore, the JavaScript interpreter chokes on non-bracketed keys containing dashes, confusing them for minus signs.

UPDATE: Thanks to Mislav’s comment below, I ended up researching this issue in a bit more depth and posted a patch which has been included in Prototype. Prototype’s Element.getStyle now accepts both camelized and non-camelized strings.

Comments

  • Mislav
    Mislav says:

    If the second line from the last example is really wrong right now, how about – while you’re on it – patching the thing to accept strings in both forms?

    I don’t believe it would be too hard…

    Wed, November 22 at 06:36 AM

  • Mislav
    Mislav says:

    You forgot about a trick or two to reduce that kind of an overhead :) Don’t worry, I’ll remind you – I’ll probably post a follow-up patch tomorrow from which you’ll see what I mean.

    Wed, November 22 at 12:08 PM

Comments are closed