A Style All Their Own
June 12, 2008 at 10:49 am by Luke Smith | In Development | 8 CommentsModifying a DOM element’s style during user interaction is one of the
pillars of creating DHTML interfaces that transition from state to state in a
smooth, and (hopefully) intuitive way. Every HTMLElement in the DOM
contains style, a collection of properties corresponding to the
CSS properties understood by the browser. For JavaScript and CSS enabled browsers, the following two paragraphs would contain red text:
<-- Paragraph 1 -->
<p style="color: #f00">This paragraph is red</p>
<-- Paragraph 2 -->
<p id="x">This paragraph's color will be red after the JavaScript runs</p>
<script type="text/javascript">
(function () {
var el = document.getElementById('x');
el.style.color = '#f00';
})();
</script>
Even CSS properties that aren’t applicable to a given element will have representation in that element’s style collection. For example, even the <br> element will have the el.style.letterSpacing property.
Names have been changed to protect the innocent
The style property names in JavaScript are camel cased versions of their CSS
counterparts, so font-family in CSS becomes
el.style.fontFamily in the style collection. "float" is a reserved word in
JavaScript, so the CSS float property is given a different name. In Internet
Explorer, styleFloat is used, where Firefox, Safari, and Opera all
use cssFloat (Opera also supports styleFloat, actually). Additionally, each browser has a host of proprietary CSS properties that also show up in the style collection (e.g. -moz-border-radius, which becomes el.style.MozBorderRadius in Firefox). Other than styleFloat/cssFloat, the browser vendors largely agree on non-proprietary property names.
The madness and the method
I set out to document which properties were present in each A Grade browser’s style collection (making no claims about their functional support for specific values).
For each browser, I used a simple for (var prop in el.style) method to iterate the style collection, and cross checked in a development tool if available. Specifically, I used the following:
| Browser | Method |
|---|---|
| Internet Explorer 6 | for ( in ) and Visual Web Developer 2008 Express Edition |
| Internet Explorer 7 | for ( in ) and Visual Web Developer 2008 Express Edition |
| Firefox 2.0.0.14 | for ( in ) and FireBug 1.1 |
| Firefox 3 (Release Candidate 2) | for ( in ) and FireBug 1.1 |
| Safari 3.1.1 (WebKit build 4525.18) | Dom Inspector* |
| Opera 9.27 | for ( in ) |
| Opera 9.5 (beta and GA) | for ( in ) and Opera Dragonfly |
* – Safari does not enumerate unassigned style properties, so for ( in ) doesn’t show anything useful.
All tests were done on a Macbook Pro running OSX 10.4. The IEs and FF2 were tested on Parallels instances running Windows XP. I only documented properties that weren’t prefixed with a vendor identifier (e.g. -moz), and omitted methods and meta fields such as setProperty and length. The only exception to this being cssText, which I’ll talk more about later. So without further ado…
Style properties across A Grade (plus a few) browsers
Properties with gold backgrounds are present in all tested browsers.
| Property | IE6 | IE7 | FF2 | FF3 | S3 | Op9.27 | Op9.5 |
|---|---|---|---|---|---|---|---|
| accelerator | Y | Y | N | N | N | N | N |
| alignmentBaseline | N | N | N | N | Y | N | Y |
| azimuth | N | N | Y | Y | N | N | N |
| background | Y | Y | Y | Y | Y | Y | Y |
| Attachment | Y | Y | Y | Y | Y | Y | Y |
| Color | Y | Y | Y | Y | Y | Y | Y |
| Image | Y | Y | Y | Y | Y | Y | Y |
| Position | Y | Y | Y | Y | Y | Y | Y |
| X | Y | Y | N | N | N | N | N |
| Y | Y | Y | N | N | N | N | N |
| Repeat | Y | Y | Y | Y | Y | Y | Y |
| baselineShift | N | N | N | N | Y | N | Y |
| behavior | Y | Y | N | N | N | N | N |
| border | Y | Y | Y | Y | Y | Y | Y |
| Top, Right, Bottom, Left | Y | Y | Y | Y | Y | Y | Y |
| Color | Y | Y | Y | Y | Y | Y | Y |
| Style | Y | Y | Y | Y | Y | Y | Y |
| Width | Y | Y | Y | Y | Y | Y | Y |
| Color | Y | Y | Y | Y | Y | Y | Y |
| Style | Y | Y | Y | Y | Y | Y | Y |
| Width | Y | Y | Y | Y | Y | Y | Y |
| Collapse | Y | Y | Y | Y | Y | Y | Y |
| Spacing | N | N | Y | Y | N | Y | Y |
| bottom | Y | Y | Y | Y | Y | Y | Y |
| boxSizing | N | N | N | N | N | N | Y |
| captionSide | N | N | Y | Y | Y | Y | Y |
| clear | Y | Y | Y | Y | Y | Y | Y |
| clip | Y | Y | Y | Y | Y | Y | Y |
| Path | N | N | N | N | Y | N | Y |
| Rule | N | N | N | N | Y | N | Y |
| color | Y | Y | Y | Y | Y | Y | Y |
| Interpolation | N | N | N | N | Y | N | Y |
| Filters | N | N | N | N | Y | N | Y |
| Profile | N | N | N | N | N | N | Y |
| Rendering | N | N | N | N | Y | N | Y |
| columnSpan | N | N | N | N | N | N | Y |
| content | N | N | Y | Y | N | Y | Y |
| counterIncrement | N | N | Y | Y | N | Y | Y |
| counterReset | N | N | Y | Y | N | Y | Y |
| cssFloat | N | N | Y | Y | Y | Y | Y |
| cssText *** | Y | Y | Y | Y | Y | Y | Y |
| cue | N | N | Y | Y | N | N | N |
| After | N | N | Y | Y | N | N | N |
| Before | N | N | Y | Y | N | N | N |
| cursor | Y | Y | Y | Y | Y | Y | Y |
| direction | Y | Y | Y | Y | Y | Y | Y |
| display | Y | Y | Y | Y | Y | Y | Y |
| displayAlign | N | N | N | N | N | N | Y |
| dominantBaseline | N | N | N | N | N | N | Y |
| elevation | N | N | Y | Y | N | N | N |
| emptyCells | N | N | Y | Y | Y | Y | Y |
| enableBackground | N | N | N | N | N | N | Y |
| fill | N | N | N | N | Y | N | Y |
| Opacity | N | N | N | N | Y | N | Y |
| Rule | N | N | N | N | Y | N | Y |
| filter | Y | Y | N | N | Y | N | Y |
| floodColor | N | N | N | N | Y | N | Y |
| floodOpacity | N | N | N | N | Y | N | Y |
| font | Y | Y | Y | Y | Y | Y | Y |
| Family | Y | Y | Y | Y | Y | Y | Y |
| Size | Y | Y | Y | Y | Y | Y | Y |
| Adjust | N | N | Y | Y | N | Y | Y |
| Stretch | N | N | Y | Y | N | Y | Y |
| Style | Y | Y | Y | Y | Y | Y | Y |
| Variant | Y | Y | Y | Y | Y | Y | Y |
| Weight | Y | Y | Y | Y | Y | Y | Y |
| glyphOrientationHorizontal | N | N | N | N | N | N | Y |
| glyphOrientationVertical | N | N | N | N | N | N | Y |
| height | Y | Y | Y | Y | Y | Y | Y |
| imageRendering | N | N | N | N | N | N | Y |
| imeMode | Y | Y | N | Y | N | N | N |
| kerning | N | N | N | N | N | N | Y |
| layoutFlow | Y | Y | N | N | N | N | N |
| layoutGrid | Y | Y | N | N | N | N | N |
| Char | Y | Y | N | N | N | N | N |
| Line | Y | Y | N | N | N | N | N |
| Mode | Y | Y | N | N | N | N | N |
| Type | Y | Y | N | N | N | N | N |
| left | Y | Y | Y | Y | Y | Y | Y |
| letterSpacing | Y | Y | Y | Y | Y | Y | Y |
| lightingColor | N | N | N | N | Y | N | Y |
| lineBreak | Y | Y | N | N | N | N | N |
| lineHeight | Y | Y | Y | Y | Y | Y | Y |
| lineIncrement | N | N | N | N | N | N | Y |
| listStyle | Y | Y | Y | Y | N | Y | Y |
| Image | Y | Y | Y | Y | Y | Y | Y |
| Position | Y | Y | Y | Y | Y | Y | Y |
| Type | Y | Y | Y | Y | Y | Y | Y |
| margin | Y | Y | Y | Y | N | Y | Y |
| Top, Right, Bottom, Left | Y | Y | Y | Y | Y | Y | Y |
| markerEnd | N | N | N | N | Y | N | Y |
| markerMid | N | N | N | N | Y | N | Y |
| markerOffset | N | N | Y | Y | N | Y | Y |
| markerStart | N | N | N | N | Y | N | Y |
| marks | N | N | Y | Y | N | Y | Y |
| mask | N | N | N | N | Y | N | Y |
| maxHeight | N | Y | Y | Y | Y | Y | Y |
| maxWidth | N | Y | Y | Y | Y | Y | Y |
| minHeight | Y | Y | Y | Y | Y | Y | Y |
| minWidth | N | Y | Y | Y | Y | Y | Y |
| navDown | N | N | N | N | N | N | Y |
| navIndex | N | N | N | N | N | N | Y |
| navLeft | N | N | N | N | N | N | Y |
| navRight | N | N | N | N | N | N | Y |
| navUp | N | N | N | N | N | N | Y |
| opacity | N | N | Y | Y | Y | Y | Y |
| orphans | N | N | Y | Y | Y | Y | Y |
| outline | N | N | Y | Y | N | Y | Y |
| Color | N | N | Y | Y | Y | Y | Y |
| Offset | N | N | Y | Y | N | N | Y |
| Style | N | N | Y | Y | Y | Y | Y |
| Width | N | N | Y | Y | Y | Y | Y |
| overflow | Y | Y | Y | Y | Y | Y | Y |
| X | Y | Y | Y | Y | Y | N | Y |
| Y | Y | Y | Y | Y | Y | N | Y |
| padding | Y | Y | Y | Y | Y | Y | Y |
| Top, Right, Bottom, Left | Y | Y | Y | Y | Y | Y | Y |
| page | N | N | Y | Y | N | Y | Y |
| BreakAfter | Y | Y | Y | Y | Y | Y | Y |
| BreakBefore | Y | Y | Y | Y | Y | Y | Y |
| BreakInside | N | N | Y | Y | Y | Y | Y |
| pause | N | N | Y | Y | N | Y | Y |
| After | N | N | Y | Y | N | Y | Y |
| Before | N | N | Y | Y | N | Y | Y |
| pitch | N | N | Y | Y | N | N | N |
| Range | N | N | Y | Y | N | Y | Y |
| pointerEvents | N | N | N | N | Y | N | Y |
| position | Y | Y | Y | Y | Y | Y | Y |
| quotes | N | N | Y | Y | N | Y | Y |
| resize | N | N | N | N | Y | N | N |
| richness | N | N | Y | Y | N | N | N |
| right | Y | Y | Y | Y | Y | Y | Y |
| rowSpan | N | N | N | N | N | N | Y |
| rubyAlign | Y | Y | N | N | N | N | N |
| rubyOverhang | Y | Y | N | N | N | N | N |
| rubyPosition | Y | Y | N | N | N | N | N |
| scrollbar3dlightColor | Y | Y | N | N | N | N | Y |
| scrollbarArrowColor | Y | Y | N | N | N | N | Y |
| scrollbarBaseColor | Y | Y | N | N | N | N | Y |
| scrollbarDarkShadowColor | Y | Y | N | N | N | N | N |
| scrollbarDarkshadowColor | N | N | N | N | N | N | Y |
| scrollbarFaceColor | Y | Y | N | N | N | N | Y |
| scrollbarHighlightColor | Y | Y | N | N | N | N | Y |
| scrollbarShadowColor | Y | Y | N | N | N | N | Y |
| scrollbarTrackColor | Y | Y | N | N | N | N | Y |
| shapeRendering | N | N | N | N | Y | N | Y |
| size | N | N | Y | Y | N | Y | Y |
| solidColor | N | N | N | N | N | N | Y |
| solidOpacity | N | N | N | N | N | N | Y |
| speak | N | N | Y | Y | N | Y | Y |
| Header | N | N | Y | Y | N | N | N |
| Numeral | N | N | Y | Y | N | N | N |
| Punctuation | N | N | Y | Y | N | N | N |
| speechRate | N | N | Y | Y | N | Y | Y |
| stopColor | N | N | N | N | Y | N | Y |
| stopOpacity | N | N | N | N | Y | N | Y |
| stress | N | N | Y | Y | N | N | N |
| stroke | N | N | N | N | Y | N | Y |
| Dasharray | N | N | N | N | Y | N | Y |
| Dashoffset | N | N | N | N | Y | N | Y |
| Linecap | N | N | N | N | Y | N | Y |
| Linejoin | N | N | N | N | Y | N | Y |
| Miterlimit | N | N | N | N | Y | N | Y |
| Opacity | N | N | N | N | Y | N | Y |
| Width | N | N | N | N | Y | N | Y |
| styleFloat | Y | Y | N | N | N | Y | Y |
| tableLayout | Y | Y | Y | Y | Y | Y | Y |
| textAlign | Y | Y | Y | Y | Y | Y | Y |
| Last | Y | Y | N | N | N | N | N |
| textAutospace | Y | Y | N | N | N | N | N |
| textAnchor | N | N | N | N | Y | N | Y |
| textDecoration | Y | Y | Y | Y | Y | Y | Y |
| Blink (bool) | Y | Y | N | N | N | N | N |
| LineThrough (bool) | Y | Y | N | N | N | N | N |
| None (bool) | Y | Y | N | N | N | N | N |
| Overline (bool) | Y | Y | N | N | N | N | N |
| Underline (bool) | Y | Y | N | N | N | N | N |
| textIndent | Y | Y | Y | Y | Y | Y | Y |
| textJustify | Y | Y | N | N | N | N | N |
| Trim | Y | Y | N | N | N | N | N |
| textKashida | Y | Y | N | N | N | N | N |
| Space | Y | Y | N | N | N | N | N |
| textOverflow | Y | Y | N | N | N | N | N |
| textRendering | N | N | N | N | Y | N | Y |
| textShadow | N | N | Y | Y | Y | Y | Y |
| textTransform | Y | Y | Y | Y | Y | Y | Y |
| textUnderlinePosition | Y | Y | N | N | N | N | N |
| top | Y | Y | Y | Y | Y | Y | Y |
| unicodeBidi | Y | Y | Y | Y | Y | Y | Y |
| vectorEffect | N | N | N | N | N | N | Y |
| verticalAlign | Y | Y | Y | Y | Y | Y | Y |
| viewportFill | N | N | N | N | N | N | Y |
| Opacity | N | N | N | N | N | N | Y |
| visibility | Y | Y | Y | Y | Y | Y | Y |
| voiceFamily | N | N | Y | Y | N | Y | Y |
| volume | N | N | Y | Y | N | Y | Y |
| whiteSpace | Y | Y | Y | Y | Y | Y | Y |
| widows | N | N | Y | Y | Y | Y | Y |
| width | Y | Y | Y | Y | Y | Y | Y |
| wordSpacing | Y | Y | Y | Y | Y | Y | Y |
| wordWrap | Y | Y | N | N | Y | N | N |
| writingMode | Y | Y | N | N | Y | N | Y |
| zIndex | Y | Y | Y | Y | Y | Y | Y |
| zoom | Y | Y | N | N | N | N | N |
A note on style.cssText
The DOM level2 spec defines the cssText property as
The parsable textual representation of the declaration block (excluding the surrounding curly braces). Setting this attribute will result in the parsing of the new value and resetting of all the properties in the declaration block including the removal or addition of properties.
That means you can set all your style attributes in one go by setting el.style.cssText = myCSSTextString. Additionally, the correct format for the string is normal CSS syntax, such as what you would assign in a tag’s style attribute (<p style="color: red; padding: 1em 2em; border-bottom: 2px solid #ccc">Hello world</p>). You can even set properties more than once in the same string, and the browsers will reconcile the duplication as it would when parsing a stylesheet.
There are some caveats with using cssText for assignment, however.
- Opera will throw an error if there is any malformed CSS in the string. (The spec recommends throwing an error if the value assigned
has a syntax error and is unparsable
. There’s a discussion as to what would make a value "unparsable" CSS, but all other browsers silently ignore declarations they don’t understand.) - Firefox 2 can alter the y value of background-position when reusing the current value of
cssTextin the assignment (such as appending with +=). This is fixed in FF3.
There may be other considerations as well that I haven’t yet discovered. On the flip side, benchmarking has shown that assigning a single property via cssText is only slightly slower than setting the corresponding property in the style collection, and setting more than one property is significantly faster via cssText. Opera 9.27 is the only exception to this, where it was always faster (in my tests, at least) to set the style properties directly.
Have fun getting your style on!
Share and extend: Bookmark with Yahoo! My Web | Bookmark with del.icio.us | digg it! | reddit!
8 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment

Copyright © 2006-2010 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service
Powered by WordPress on Yahoo! Web Hosting.


I’ve been known to use a technique like this to detect CSS support from JavaScript in rare situations.
if (!YAHOO.lang.isUndefined(n.style.maxWidth))Comment by Chris Griego — June 12, 2008 #
In FF2+ you can’t get css ‘background-position’ value in JavaScript.
Of course if you set it in JavaScript you’ll get it.
And in FF2+ negative ‘z-index’ value of (‘absolute’, ‘relative’, ‘fixed’) element makes that element not visible.
Both should be fixed in FF3
Just my 2 cents
Regards
Darek
Comment by Darek Adamkiewicz — June 12, 2008 #
This is great. Would you consider updating this chart to repeat the headings (browsers) every 30 or 50 rows or so?
Comment by 5307853 — June 12, 2008 #
Very useful, thanks. Any idea whether changing
cssTextis faster than changing the class?Comment by Matt Robinson — June 13, 2008 #
Considering that Opera 9.5 was released yesterday, I don’t see why you would use a really old beta version of the browser. Current build number is 10063, while the version you tested is build number 4808.
Comment by Marius-Remus Mate — June 13, 2008 #
[...] Click through to see the full table of CSS properties. [...]
Pingback by A Style All Their Own « outaTiME — June 13, 2008 #
@Matt,
I didn’t benchmark assigning cssText vs setting the className. Generally speaking, setting element style directly is only preferable when you need to assign dynamic values. Besides being better practice, it is most likely faster to update className because the browser does not need to do the extra step of parsing the cssText and updating the properties in the element’s style collection before the repaint.
@Marius-Remus
I might have misread the build number. I’ve since installed 9.5 GA and verified there were no modifications to the style collection members. Incidentally, Dragonfly shows ‘audio-level’, ‘rest’, ‘rest-after’, and ‘rest-before’, but they apparently don’t have representation in the style collection as audioLevel (etc).
Comment by Luke — June 13, 2008 #
Tip: Change multiple attributes in multiple elements at once.
multipleSpans=YAHOO.util.Dom.getElementsByClassName(‘multiple’, ’span’);
YAHOO.util.Dom.setStyle(multipleSpans, ‘cssText’,'text-decoration:underline;cursor:pointer;’);
Comment by Ben Swieringa — June 23, 2008 #