Querying Overall Styles

If you want to query the overall styles from the CSS cascade for an element, you want to know the declarations that have the highest precedence. Those form one humongous declaration block, which, like the declaration block for a rule, JavaScript represents with a CSSStyleDeclaration object. The cumulative declaration block from the cascade differs from that of a rule in a style sheet in a few ways:

  • It is read-only. Try to assign a new value to a property from the cascade, and JavaScript calls you a dummy by way of an error.
  • Any relative values are converted to absolute values. Typically this means converting the value to pixels.
  • Any property that sets several properties in one fell swoop, such as a margin or border, may contain undefined, while their corresponding fully expanded properties, such as marginLeft or borderRightStyle, will always contain a value. As a rule of thumb, do not query rollup values from the cascade. Query their fully expanded equivalents instead.

Lets create a helper function named queryCascade() that works with two parameters:

  • element will contain an Element node for the DOM tree.
  • property will contain the name of the CSS property as a camel case string.

Don’t pass a dash case string or a camel case identifier.

Now let’s send Firefox, Safari, and Opera down one path and Internet Explorer down another by way of an if statement and the else if idiom. First let’s test for the DOM function

MethodDescription
getComputedStyle()by way of the typeof operator. If typeof returns "function" rather than "undefined", invoke with two parameters, element and null.
getComputedStyle()will then return a CSSStyleDeclaration object containing the cumulative declarations from the cascade, as well as those implicitly calculated by the browser, for element. Then query property by way of the [] operator.
function queryCascade(element, property) {
    if (typeof getComputedStyle === "function") {
        return getComputedStyle(element, null)[property];
    }
}

We use null for the second parameter because this can be a pseudo-element as a string, for example, ":before" or ":after". However, Internet Explorer’s proprietary alternative to getComputedStyle() does not support pseudo-elements. Therefore, pass null to make things work crossbrowser.

Internet Explorer does not implement the ViewCSS interface that provides getComputedStyle(). Internet Explorer’s way is simple: an Element node has not only a style member for inline styles but also a currentStyle member for cascade styles. Both style and currentStyle contain a CSSStyleDeclaration object.

Now let’s query a CSS property from the cascade. Then we have a couple that were calculated behind the scenes by Firefox:

snippet
function queryCascade(element, property) {
    if (typeof getComputedStyle === "function") {
        return getComputedStyle(element, null)[property];
    } else if (element.currentStyle) {
        return element.currentStyle[property];
    }
}
Output
queryCascade(document.getElementById("adidas"), "width"); // "100px" queryCascade(document.getElementsByTagName("ul")[0], "width"); // "120px" queryCascade(document.getElementsByTagName("ul")[0], "height"); // "0px"

For the Adidas <a> element, queryCascade() returned the value from an explicit declaration in eight.css. On the other hand, the values for the <ul> element were calculated behind the scenes for us by Firefox. Note that insofar as the <ul> is a block element, its width is set to that of the containing <div>, which we set to "120px". On the other hand, since the <a> elements within the <ul> are absolutely positioned relative to the <div> and the <li> has a display value of inline, the <ul> collapses to a height of "0px".

Here is the situation. Nowadays, CSS presentation and markup content are in separate files. Initially, the CSSStyleDeclaration object in the style member for an Element node will be irrelevant, with just scores of "" empty strings and other default values. On the other hand, the CSSStyleDeclaration object representing cascade declarations is totally relevant but read-only. So if you do not know what rule or style sheet contains the declaration with the highest precedence, then what do you do? Typically, scripters read the cascade and write the inline style attribute. That is to say, they query two separate CSSStyleDeclaration objects. Obviously, if you know where to find the rule, then you simply read and write the CSSStyleDeclaration object representing the rule’s declaration block, But, you won’t have that option.

Lets read the cascade, write the attribute.

Save the <div> to a variable named myDIV. Pass myDIV and "left" to queryCascade(), which will then return "40px". Convert that string to the number 40 by way of parseInt(), and then add 10. Next, convert the sum of 50 to the string "50", and append "px". Finally, write that string, "50px", to the style attribute. Click Run repeatedly until left is set to "700px". JavaScript will move our running shoe menu to the right by 10 pixels each time you click Run.

var myDIV = document.getElementById("running");
myDIV.style.left = parseInt(queryCascade(myDIV, "left")) + 10 + "px";

JavaScript animations typically work in this way by writing the style attribute at regular intervals.

Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents +