David Mark's Daily Javascript Tips - Volume #3 - Tip #8 - How toCompute Styles

Discussion in 'Javascript' started by David Mark, Dec 6, 2011.

  1. David Mark

    David Mark Guest

    How to Compute Styles

    In a word, don't. The recommendation followed by the browser vendors
    is long-winded and vague and historically browsers have varied in
    their interpretations. The variety of results that must be parsed to
    derive meaning is a huge burden to bear and most applications don't
    need to compute any styles (let alone all possibilities!) in the first
    place.

    var getStyleComputed;

    // No "float" styles
    // Requires camel-case style names
    // Fades away in IE 8- and compatibility modes

    if (document.defaultView && document.defaultView.getComputedStyle) {
    getStyleComputed = function(el, style) {
    return document.defaultView.getComputedStyle(el, null)
    [style];
    };
    }

    What's missing? Can't handle "float" as it is a reserved word
    (property is "cssFloat" or "styleFloat", depending on
    implementation). That's easy enough to detect, but how often do you
    need to compute the float style?

    Add a line during development:-

    if (document.defaultView && document.defaultView.getComputedStyle) {
    getStyleComputed = function(el, style) {

    if (style == 'float') {
    throw new Error('RTFM! The "float" style is not
    supported by this rendition!');
    }

    return document.defaultView.getComputedStyle(el, null)
    [style];
    };
    }

    ....and remove on release.

    Note that this function requires camel-case style names, not
    hyphenated. That will save you a keystroke/byte. ;)

    Add another line during development:-

    if (document.defaultView && document.defaultView.getComputedStyle) {
    getStyleComputed = function(el, style) {

    if (style.indexOf('-') != -1) {
    throw new Error('Camel-case style names, please.');
    }

    if (style == 'float') {
    throw new Error('RTFM! The "float" style is not
    supported by this rendition!');
    }

    return document.defaultView.getComputedStyle(el, null)
    [style];
    };
    }

    ....and remove on release.

    Instead of adding additional logic for your users to *download*,
    simply corral your developers prior to release.

    if (getStyleComputed) {
    // Put app that must compute styles here
    }

    But what of IE8 and under? At this point, you have to consider what
    this function is to be used for. There's not a chance in hell in
    creating a general-purpose getComputedStyle emulation for legacy IE
    versions (which lack the required host method). And no, that fact has
    not stopped the library ninjas from trying to outdo each other, year
    after year, on this front. Even worse, these teetering piles of hacks
    are often tangled up with other library functionality (e.g. jQuery's
    height/width methods). The situation is a mess that can only be
    cleaned up by starting over from scratch (as jQuery is rumored to be
    contemplating).

    Historically, the primary use of such "cross-browser" wrappers has
    been to support scripted effects. Well, scripted effects are dead
    these days (somebody tell jQuery) and even if you need to offer
    fallback effects for legacy IE versions, you don't need a cross-
    browser getComputedStyle wrapper. You just need to concentrate on
    whatever handful of styles your current project must animate.

    Left, top, right, bottom, height, width and borders can all be easily
    figured without a getComputedStyle dependency. Margins can be figured
    in some contexts, but who would need to do such a thing? And I can
    hear it now: what about padding?! Unless you are doing something very
    wrong, you should never need to compute the padding. Granted, that's
    exactly what jQuery's height/width methods try to do. :(

    Here are solutions for size and position:-

    http://www.cinsoft.net/size.html
    http://www.cinsoft.net/position.html

    Borders should be an easy exercise if you have been following along;
    yes, even the right and bottom borders. But why would your script be
    interested in such styling, unless it is going to do scripted effects
    involving borders?

    I've been using the CSS3 transitions/animations for some time now.
    I've seen Opera, then Firefox (and finally IE 10) reproduce what
    Webkit started and have been quite pleased with the consistency and
    performance. It takes little or no code to use those features. So
    use them and stop worrying about computed styles.

    Take out effects, computing styles, queries, and all of the other
    topics covered so far in this series and what is there left for a
    script like jQuery to do; other than take up space? Pretty hard to
    believe that ostensibly experienced developers are now trying to build
    a "mobile framework" on top of jQuery. All I can figure is they have
    no idea what is in that script. For them, I guess it's all about
    marketing a name. :(

    http://www.cinsoft.net/
    http://twitter.com/cinsoft
    http://jsperf.com/browse/david-mark
     
    David Mark, Dec 6, 2011
    #1
    1. Advertising

  2. David Mark

    David Mark Guest

    Re: David Mark's Daily Javascript Tips - Volume #3 - Tip #8 - How toCompute Styles

    On Dec 6, 6:28 pm, David Mark <> wrote:
    > How to Compute Styles
    >
    > In a word, don't.  The recommendation followed by the browser vendors
    > is long-winded and vague and historically browsers have varied in
    > their interpretations.  The variety of results that must be parsed to
    > derive meaning is a huge burden to bear and most applications don't
    > need to compute any styles (let alone all possibilities!) in the first
    > place.
    >
    > var getStyleComputed;
    >
    > // No "float" styles
    > // Requires camel-case style names
    > // Fades away in IE 8- and compatibility modes
    >
    > if (document.defaultView && document.defaultView.getComputedStyle) {
    >           getStyleComputed = function(el, style) {
    >             return document.defaultView.getComputedStyle(el, null)
    > [style];
    >           };
    >
    > }
    >
    > What's missing?  Can't handle "float" as it is a reserved word
    > (property is "cssFloat" or "styleFloat", depending on
    > implementation).  That's easy enough to detect, but how often do you
    > need to compute the float style?
    >
    > Add a line during development:-
    >
    > if (document.defaultView && document.defaultView.getComputedStyle) {
    >           getStyleComputed = function(el, style) {
    >
    >             if (style == 'float') {
    >               throw new Error('RTFM! The "float" style is not
    > supported by this rendition!');
    >             }
    >
    >             return document.defaultView.getComputedStyle(el, null)
    > [style];
    >           };
    >
    > }
    >
    > ...and remove on release.
    >
    > Note that this function requires camel-case style names, not
    > hyphenated.  That will save you a keystroke/byte.  ;)
    >
    > Add another line during development:-
    >
    > if (document.defaultView && document.defaultView.getComputedStyle) {
    >           getStyleComputed = function(el, style) {
    >
    >             if (style.indexOf('-') != -1) {
    >               throw new Error('Camel-case style names, please.');
    >             }
    >
    >             if (style == 'float') {
    >               throw new Error('RTFM! The "float" style is not
    > supported by this rendition!');
    >             }
    >


    And how about:-

    if (el.style.display == 'none') {
    throw new Error('Element not in layout. Cannot compute
    styles.');
    }

    ....as any calling code that passes an element that is not part of the
    layout (presumably removed by the script) is clearly making a
    mistake. Computed styles have no meaning in that context.

    Best to fail immediately so the developer can follow the stack trace
    back to the offending code.

    Again, remove such "scaffolding" on deployment, at which time should
    be rendered no-ops anyway (else testers missed something).

    And, of course, some libraries and frameworks will try like hell to
    make sense out of such illogical situations, shielding the developers
    from fundamental misunderstandings in their own code. They call it
    being "forgiving". In general, it's just stupid to write an API like
    that. For browser scripting, it's certainly ill advised and writing
    things like UI widgets with such a "forgiving" API is madness.

    And that's where the lists of "approved" browsers creep in, to let
    developers know these monoliths can't possibly be expected to work in
    anything but the last five or six browsers tested. They just have no
    idea beyond that (and refuse to find out). Anything else, past or
    future, is your own problem; you saw the browser icons when you
    downloaded the library. :(

    >             return document.defaultView.getComputedStyle(el, null)
    > [style];
    >           };
    >
    > }
     
    David Mark, Dec 7, 2011
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Mark
    Replies:
    16
    Views:
    943
    Scott Sauyet
    Nov 11, 2011
  2. David Mark
    Replies:
    58
    Views:
    1,544
    David Mark
    Dec 6, 2011
  3. David Mark
    Replies:
    6
    Views:
    773
    Dr J R Stockton
    Nov 16, 2011
  4. David Mark
    Replies:
    8
    Views:
    657
    Thomas 'PointedEars' Lahn
    Dec 10, 2011
  5. David Mark
    Replies:
    1
    Views:
    743
    dhtml
    Dec 17, 2011
Loading...

Share This Page