JavaScript: The Definitive GuideJavaScript: The Definitive GuideSearch this book

18.5. Other DOM APIs for Styles and Style Sheets

So far in this chapter, we've discussed a simple DOM API for working with CSS styles: every HTMLElement in a document has a style property that represents the inline style attributes of that element. The style property refers to a CSS2Properties object that defines a JavaScript property for each CSS style attribute defined by the CSS2 standard.

Although we've made extensive use of it, the CSS2Properties object is just one part of the DOM API for CSS.[69] This section provides a quick overview of the rest of the DOM API for working with CSS style sheets. Note, however, that at the time of this writing, much of the CSS API is not well supported by current (sixth-generation) browsers. You should test carefully before relying on any of the APIs described here.

[69]In fact, the CSS2Properties object is optional. A DOM implementation may support CSS without supporting CSS2Properties. In practice, however, this is the most commonly used API for working with styles, and DOM implementations in web browsers are effectively required to support it.

18.5.1. Style Declarations

The CSS2Properties interface is a subinterface of CSSStyleDeclaration. Thus, the style property of each document element also implements the properties and methods of CSSStyleDeclaration. The methods include setProperty( ) and getPropertyValue( ), which you can use as an alternative to setting and querying the individual style properties of CSS2Properties. For example, these two lines of code accomplish the same thing:

element.style.fontFamily = "sans-serif";
element.style.setProperty("font-family", "sans-serif", ""); 

Other features of the CSSStyleDeclaration interface are the removeProperty( ) method, which deletes a named style, and the cssText property, which returns a text representation of all the style attributes and their values. Since CSSStyleDeclaration objects represent a set of style attributes and their values, they can also be used as arrays to iterate through the names of the style attributes.

18.5.2. Computed Styles

As I emphasized earlier in this chapter, the style property of a document element represents the style attribute for that element, and it does not contain any information about other styles (from style sheets) that affect that element. To determine the complete set of styles that apply to an element, use the getComputedStyle( ) method of the Window object (this method is defined by the AbstractView interface: see the "AbstractView.getComputedStyle( )" entry in the DOM reference section). The return value of this method is a CSSStyleDeclaration object that describes all the styles that apply to the specified element. You can assume that the returned object also implements the CSS2Properties interface, just as the style property of an element does.

To illustrate the difference between an element's inline style and its computed style, consider an element e. To determine whether e has a font specified in its inline style attribute, you can do this:

var inlinefont = e.style.fontFamily; 

But to determine what font family e is displayed in (regardless of whether this is specified by an inline style or by a style sheet), do this instead:

var fontfamily = window.getComputedStyle(e, null).fontFamily; 

You may prefer to use getComputedStyle( ) in a way that makes it clearer that it is defined by the AbstractView interface:

var fontfamily = document.defaultView.getComputedStyle(e, null).fontFamily; 

The style values returned by getComputedStyle( ) are read-only, since they come from various places in the style cascade. Setting any of the attributes has no effect on the style of the element. The getComputedStyle( ) method should also be considered "expensive," since it must traverse the entire cascade and build a large CSSStyleDeclaration representing the many style attributes that apply to the element.

Finally, note that IE 5 and later define a nonstandard but useful currentStyle property in addition to the style property for all HTML elements. currentStyle refers to a CSS2Properties object that holds the computed style for that element.

18.5.3. Override Styles

The CSS standard specifies that a web browser have a default style sheet that defines the basic display styles of HTML elements. The browser may allow the user to specify a user style sheet that represents the user's style preferences and overrides styles specified in the default style sheet. Author style sheets are style sheets defined by a document's author -- that is, the styles included in or linked into a document. Author style sheets override the browser's default styles and the user's styles (except for !important styles). Inline styles specified with the style attribute of an element can be considered part of the author style sheet.

The DOM standard introduces the notion of an override style sheet that overrides the author style sheet, including inline styles. By setting styles for an element in the override style sheet, you can change the displayed style of an element without modifying the document's style sheets or the inline style of that element. To obtain the override style of an element, use the getOverrideStyle( ) method of the Document object:

var element = document.getElementById("title");
var override = document.getOverrideStyle(element, null); 

This method returns a CSSStyleDeclaration object (which also implements CSS2Properties) that you can use to change the displayed style of an element. Note the difference between setting an override style and an inline style:

override.backgroundColor = "yellow";     // Sets an override style
element.style.backgroundColor = "pink";  // Sets an inline style

18.5.4. Creating Style Sheets

The DOMImplementation object (accessed as document.implementation) defines a createCSSStyleSheet( ) method for creating CSSStyleSheet objects. The CSSStyleSheet object defines an insertRule( ) method that you can use to add style rules to the style sheet. Unfortunately, DOM Level 2 does not define any way to associate a created style sheet with a document, so there is currently no point in using this method. Future versions of the DOM standard may remedy this.

18.5.5. Traversing Style Sheets

The core DOM API makes it possible to traverse an HTML (or XML) document and examine every element, attribute, and Text node of the document. Similarly, the style sheets and CSS modules of the DOM make it possible to examine all the style sheets in or linked into a document and to traverse those style sheets, examining all the rules, selectors, and style attributes that comprise them.

For scripters who want to create DHTML, it is usually sufficient simply to work within the inline styles of elements using the API shown earlier in this chapter, and it is not typically necessary to traverse style sheets. Nevertheless, this section briefly introduces the DOM API for style-sheet traversal. You can find further details on the API in the DOM reference section. At the time of this writing this API is not well supported, but support in Mozilla is expected soon. Note also that IE 5 defines a proprietary and incompatible API for traversing style sheets.

The style sheets that are included in or linked into a document are accessible through the document.styleSheets[] array. For example:

var ss = document.styleSheets[0]; 

The elements of this array are StyleSheet objects. StyleSheet represents a generic style sheet. In HTML documents using CSS style sheets, these objects all implement the subinterface CSSStyleSheet, which provides CSS-specific properties and methods. A CSSStyleSheet object has a cssRules[] array that contains the rules of the style sheet. For example:

var firstRule = document.styleSheets[0].cssRules[0] 

The CSSStyleSheet interface also defines insertRule( ) and deleteRule( ) methods for adding and removing rules from the style sheet:

document.styleSheets[0].insertRule("H1 { text-weight: bold; }", 0); 

The elements of the CSSStyleSheet.cssRules[] array are CSSRule objects. CSS style sheets may contain a number of different types of rules. In addition to the basic style rules that we've seen in this chapter, there are various "at-rules," which are specified with keywords like @import and @page. You can read about these special types of CSS rules in a CSS reference.

The CSSRule interface is a generic one that can represent any type of rule and has subinterfaces that represent the specific rule types. The type property of CSSRule specifies the specific rule type. Most rules in a CSS style sheet are basic style rules, such as:

h1 { font-family: sans-serif; font-weight: bold; font-size: 24pt; } 

Rules of this type have a type property of CSSRule.STYLE_RULE and are represented by CSSRule objects that additionally implement the CSSStyleRule interface. CSSStyleRule objects define a selectorText property that contains the rule selector (the string "h1" in the previous rule) and a style property that contains the rule's style attributes and values (such as the font attributes in the previous rule). For example:

var rule = document.styleSheets[0].cssRules[0]
var styles;
if (rule.type == CSSRule.STYLE_RULE) styles = rule.style; 

The value of the CSSStyleRule.style property is a CSSStyleDeclaration object. We've already encountered this object: it is the same type of object that is used to represent the inline styles of document elements. It defines methods such as setProperty( ), removeProperty( ), and getPropertyValue( ). As discussed previously, CSSStyleDeclaration objects typically also implement the CSS2Properties interface and therefore define a property that corresponds to each CSS attribute.

The properties of CSS2Properties and the getPropertyValue( ) method of CSSStyleDeclaration return the values of CSS style attributes as strings. As discussed earlier in this chapter, this means that when you query the value of an attribute such as font-size (or when you read the fontSize property of CSS2Properties), what you get back is a number and a units value. This might be "24pt" or a (probably less useful) value like "10mm". In general, when you get the value of a CSS attribute as a string, you have to parse it in some way to extract the data you want from it. This is particularly true of attributes like clip, which have a complex string syntax.

As an alternative to parsing strings, CSSStyleDeclaration provides another method, getPropertyCSSValue( ), that returns the value of a CSS attribute as a CSSValue object instead of a string. The cssValueType property of the CSSValue object specifies a sub-interface that the object also implements. If an attribute has more than one value, the CSSValue object implements CSSValueList and behaves like an array of CSSValue objects. Otherwise, the CSSValue object is typically a "primitive" value and implements the CSSPrimitiveValue interface. CSSPrimitiveValue objects have a property named primitiveType that specifies the type of the value or the units that apply to the value. There are 26 possible types, all represented by constants like CSSPrimitiveValue.CSS_PERCENTAGE, CSSPrimitiveValue.CSS_PX, and CSSPrimitiveValue.CSS_RGBCOLOR. In addition to the primitiveType property and the various type constants, CSSPrimitiveValue defines various methods for setting and querying the value represented by the object. If the CSSPrimitiveValue object represents a length or percentage, for example, you call getFloatValue( ) to obtain the length. If the primitiveType property indicates that the value represents a color, you use getRGBColorValue( ) to query the color value.

Finally, the DOM CSS API also defines a few special object types to represent attribute values: RGBColor objects represent color values, Rect objects represent rectangle values (such as the value of the clip attribute), and Counter objects represent CSS2 counters. See the DOM reference section for details.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.