Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






Modifying Styles


10/05/2001

Older browsers, such as Netscape's Navigator 4 series, had relatively poor support for modifying Cascading Stylesheets from JavaScript -- instead requiring that you use either document.write() calls to rewrite the contents of a particular element or their equally burdensome (and Navigator-only) Javascript Stylesheets mechanism.

With the release of Microsoft Internet Explorer 5 and Netscape 6.0 for the Macintosh, however, we now have the ability to change styles on the fly from JavaScript, using the W3C DOM. Unfortunately, due to a distinction between the way that embedded and remote stylesheet properties are exposed as opposed to the way that inline STYLE properties are exposed, this can be tricky. In effect, developers are required to define all styles inline or in embedded stylesheets (whether internal or external) if they want to be able to read and modify them reliably. Despite the fact that stylesheets are far easier to work with, may be reused across pages, and may be designed by someone with no JavaScript knowledge, browser vendors recommend that dynamic changes be made via the JavaScript .style property directly.

For example, given the following embedded stylesheet declaration:

<style type="text/css">
H1 {
  font-family: Arial;
  font-size: 12pt;
}
</style>

You can read the properties from JavaScript as follows (note that the CSS properties themselves are camelCased rather than hyphenated):

<script type="text/javascript">
var myStyle = document.styleSheets[0].cssRules[0].style;
var fFamily = myStyle.fontFamily;
var fSize = myStyle.fontSize;
alert("H1 stylesheet:\nfamily: "
  + fFamily + "\nsize: " + fSize);
</script>

However, given the following inline style attribute on a particular H1, you need to use a different interface to read the properties:

<h1 style="font-family: Palatino;
  font-size: 14pt;">example</h1>
<script type="text/javascript">
var myH1Array = document.getElementsByTagName("H1");
var myElem = myH1Array.item(0);
var myStyle = myElem.style;
var fFamily = myStyle.fontFamily;
var fSize = myStyle.fontSize;
alert("H1 Inline:\nfamily: "
  + fFamily + "\nsize: " + fSize);
</script>

If you use the former method to read the style properties for H1, but have declared them inline as in the latter example, you get the wrong values—those defined in the embedded stylesheet, not those defined in the inline style attribute. Obviously, the problem can be resolved for named elements by reading the style properties for the element in question:

<h1 id="example"
  style="font-family: Palatino;
    font-size: 18pt;">example</h1>
<script type="text/javascript">
var myElem = document.getElementById("example");
var myStyle = myElem.style;
var fFamily = myStyle.fontFamily;
var fSize = myStyle.fontSize;
alert("H1 with ID `example':\nfamily: "
  + fFamily + "\nsize: " + fSize);
</script>

If the element in question doesn't use inline style attributes, you get empty or null values, rather than the embedded stylesheet properties you're after.

In essence, although the browser knows how to properly override global stylesheet declarations when rendering the element, there is no single built-in cross-browser way to access the style being used for that rendering. Internet Explorer has (in the 5.x generation) introduced the currentStyle and runtimeStyle collections, but they're not standard or supported in Navigator, and runtimeStyle doesn't seem to be supported in Internet Explorer 5.0 for the Macintosh.

If you want to change an element's style, a similar problem exists. If you only modify the global stylesheet for an element type for which inline styles are defined, only those elements without inline styles are changed. This may be viewed as a feature or a weakness, depending on your point of view, your particular application, and the lateness of the hour or proximity of the deadline.

There is a standard way to read the current style properties for any element, the getComputedStyle() method, but it is not yet supported on the Macintosh platform. Internet Explorer does support the currentStyle collection, which is a proprietary implementation of the method, but Navigator 6 does not yet appear to support either method reliably, if at all.

Fortunately, there is a way to read and change an element's styles regardless of where they were originally defined. As you might expect, it entails checking all the available stylesheet properties in both embedded styles and inline STYLE attributes. I've provided a script that will take some of the pain out of doing so.

The Script's Purpose

Related Reading

Designing with JavaScript, 2nd EditionDesigning with JavaScript, 2nd Edition
By Nick Heinle & Bill Peña
Table of Contents
Index
Sample Chapter
Full Description

As demonstrated above, with the increased power of the newer browsers come some compromises in ease of use for the developer. More importantly, as more and more applications are being jointly produced by developers and designers working in tandem (and sometimes without perfect communication between those implementing behavior and those implementing the look and feel) it's important to preserve flexibility in the approaches used to apply and modify style. This script helps the developer do just that.

Why would you want to modify styles on the fly? As Web applications become more and more powerful, users are demanding more flexibility and control over their personal preferences, just as they are used to having in traditional desktop applications. For instance, some users may like reading body copy in serif fonts, while others may enjoy sans-serif. Or source code listings, like those in this article, might be too small to read, so you'd want the user to be able to modify them at will. Of course, there are literally thousands of different applications for these capabilities -- I'm just pointing out some that are convenient in the context of this article.

Pages: 1, 2

Next Pagearrow