DOM Style Sheets
DOM Style Sheets allow you to step through the rules of each stylesheet, change the selectors, read and write styles, and add new rules. This allows you to create or change CSS that affects several elements at the same time, instead of just one element as with traditional DHTML. It allows you to take advantage of CSS selectors to target the desired elements, and enter rules into the CSS cascade.
Currently this is supported according to the DOM standard by Opera 9+, Mozilla/Firefox and Internet Explorer 9+ (in standards mode). It is partially supported by Safari, Chrome, Konqueror and ICEbrowser, but their support is so bad it is largely unusable. I will give details of what fails in these browsers for each operation. Supposedly you can use the hasFeature method to check if a browser supports DOM 2 Style Sheets well enough, but unfortunately Safari/Chrome and ICEbrowser return true for the StyleSheets and CSS features. Their support is so poor that this is an insult to the spec. I suggest you ignore Safari/Chrome, Konqueror and ICEbrowser for now, and hope that their support improves in the future.
If you need compatibility with Safari/Chrome, Konqueror, ICEbrowser, or any browser that does not support DOM Style Sheets (like iCab or Opera 8 or below), then you should ensure that your script does not requre document.styleSheets to be supported, and that if it uses it, it does not produce errors when something fails in one of these browsers.
Internet Explorer 8- does not comply with the standard here, so if you are testing, use a browser that supports the standard correctly, such as Opera 9+ or Mozilla. I will give details later on how to get support for Internet Explorer 8- as well. Internet Explorer 9+ only adds support for DOM Style Sheets in standards mode. In quirks mode or IE 7 compatibility mode, only the Internet Explorer model is provided, along with its limitations. Internet Explorer on Mac supports large parts of the Internet Explorer model, but it also provides the cssRules collection, even though it does not use it according to the spec. I recommend you ignore IE Mac, but I will include it in the Internet Explorer section later on in this chapter.
DOM stylesheets does not provide an exact copy of what you put in your stylesheet. It produces what the browser sees, and what it interprets. Rules that it does not understand are not included, whitespace may be added or removed, combined styles may be split into their components, and split styles may be combined. Styles that are not understood will be ignored. Comments will not be included. Do not expect to be able to recognise your own stylesheet.
Note that you should not try using DOM 2 Style Sheets until you are certain that the stylesheet has completed loading (typically this means waiting for the document's onload event to fire). If you attempt to access it before then, the cssRules collection may be too short or may not exist.
The styleSheets list
- Mozilla gives STYLE element stylesheets the address of the current page as their href property, instead of null.
- Internet Explorer 9+ incorrectly claims that stylesheets are not disabled, even when their media attribute causes them to be disabled.
- Opera 9.2- does not provide the href property for stylesheets added using XML processing instructions, and they cannot be disabled.
- Safari and Konqueror only populate the list with stylesheets that are enabled at the specific time, meaning that if you use alternate stylesheets, most of them will be missing from the list. Safari 2- and Konqueror do not provide the title property, and they do not let you modify the disabled property.
- Safari 3-, Konqueror and ICEbrowser do not include stylesheets added using XML processing instructions (ICEbrowser does not understand XML).
- Safari and Konqueror will populate the list with stylesheets that are added to the BODY with DOM, but these will have no styling effects on the document (stylesheets are only allowed in the document HEAD).
- ICEbrowser only populates the list with persistent/preferred stylesheets, meaning that if you use alternate stylesheets, they will be missing from the list.
- ICEbrowser does not add dynamically generated stylesheets into the collection.
- NetFront provides the collection but it is always empty.
All stylesheets are available through the document.styleSheets collection. This includes stylesheets added using <style>
and <link>
tags, including persistent, preferred and alternate stylesheets, no matter if they are enabled or not. Even stylesheets added using style sheet processing instructions in XML based documents should be included. They are available in the collection in the order that they appear in the document source. Imported stylesheets are not included in the list (as they are included through their parent stylesheet), and will be dealt with later. The collection does not include the contents of <div style="etc">
attributes; they must be accessed through the style property of the element (see the section on DHTML for more details).
This provides an easy way to check if a browser supports some amount of DOM Style Sheets, by checking for the existence of the document.styleSheets collection:
if( document.styleSheets ) {
//DOM stylesheets are available
}
Each stylesheet has a number of properties that give details of the stylesheet, such as its URL (href), its title (title), its type (type, usually 'text/css'
), the media types it applies to (media), and if it is disabled or not (disabled). The disabled property can be set to true or false to disable or enable the stylesheet, but the other properties are all read-only. The properties will only be available if they actually apply to the stylesheet in question. For example, if a link element does not have the title attribute set, then its associated StyleSheet object will not have a title.
Test it here: see the properties of the first stylesheet in this document.
Relationships between the StyleSheet object and the HTML tags that create them
- Safari 2- and Konqueror do not provide the sheet property for linked stylesheets.
- ICEbrowser does not provide the sheet property for any stylesheets.
If you have a reference to the LINK or STYLE element, you can reference the associated StyleSheet object using the sheet property of the element.
var theSheet = document.getElementsByTagName('style')[0].sheet;
Similarly, if you have a reference to the StyleSheet object, you can reference the associated LINK or STYLE element by using the ownerNode property of the StyleSheet object.
var theElement = document.styleSheets[0].ownerNode;
Test it here: check for these properties.
Stylesheet media
- Internet Explorer 9+ sometimes fails to redraw the page when media types are changed on linked stylesheets, but will update each part of the page as it reflows.
- Internet Explorer 9+ fails to recognise when mediaText is changed on stylesheets added with style tags, unless the tag originally had a media attribute.
- Internet Explorer 9+ incorrectly allows scripts to set invalid media types.
- Internet Explorer 9+ incorrectly returns an empty string when reading media.item(index) for out-of-bounds indexes.
- Opera 11+ fails to recognise when a change in mediaText causes the stylesheet not to apply any more.
- Safari 2- and Konqueror sometimes put an extra comma on the end of the mediaText (making it invalid).
- Safari 3-, Konqueror and ICEbrowser do not allow media types to be added or removed.
- ICEbrowser ignores media attributes, and treats mediaText as a blank string.
The media property of the stylesheet references a MediaList object. This allows adding and removing of media types. It has a property mediaText that gives the full contents of the LINK or STYLE element's media attribute. Note that browsers are free to add or remove spaces, as they decide is appropriate. They may also remove any media types they do not understand, or may rename them (typically to 'unknown'). If the text contains the same media type more than once, the browser may remove the extra copies. It is possible to set this text to a new string if desired:
document.styleSheets[0].media.mediaText = 'print,handheld';
Modifying the media types that the stylesheet applies to is mostly useful if the browser supports multiple media types. Of the browsers that support DOM stylesheets, only Opera supports more than just screen and print (Opera also supports projection, handheld, speech, and on some devices, tv). This means that currently, this feature is most useful in Opera, but can also be useful in other browsers if you wish to change between 'all', 'screen', and 'print'. Note that the browser may support media queries, and the specification never took these into account. Currently this affects Opera. Opera normalizes media queries (removing spaces and reformatting), to make sure that only one copy of each equivalent query (with parameters in the same order) exists.
If you set the mediaText to a value containing media types the browser does not recognise, it will allow that, and simply ignore unknown media types. Setting the media text to a value that the browser does not recognise as valid syntax will throw an error, so browsers that do not understand media queries will not allow you to set mediaText containing a media query. You will need to use a try...catch
statement around the assignment.
The media object also provides the appendMedium method to allow you to append one media type at a time, and the deleteMedium method to delete one at a time. Deleting a medium that is not in the list, or that the browser does not understand, will cause it to throw an error. Note that a stylesheet with no media is applied to all media types. Adding a medium to a stylesheet that has no specified media will cause it to be applied only to that media type. Deleting all media types from the list will cause the media text to be empty, so it will be applied to all media types.
document.styleSheets[0].media.appendMedium('handheld');
document.styleSheets[0].media.deleteMedium('print');
You can also step through all the listed media types using the item method, and check how many are in the list by checking the length parameter.
for( var i = 0; i < document.styleSheets[0].media.length; i++ ) {
alert(document.styleSheets[0].media.item[i]);
}
Test it here:
- Append the print media type to all stylesheets on this page.
- The page should appear to have lost all its styling information.
- You can then test if it worked by using your browser's print preview feature.
- If you are using Opera, you can also append the handheld media type to all stylesheets on this page, and test it using View - Small screen.
- Check what media types the first stylesheet is using.
- You can then delete the print media type and delete the handheld media type.
Stylesheet cssRules collection
- Mozilla does not provide this collection for alternate stylesheets that do not have a title attribute.
- Safari 2- and Konqueror cannot add or remove rules.
- Safari/Chrome, Konqueror, Internet Explorer 9+ and ICEbrowser ignore some @ rules that they do understand, such as @charset rules.
- ICEbrowser cannot add rules.
Stylesheets all have the cssRules collection, that contains all the rules of the stylesheet. This only includes rules that are in the root of the stylesheet, and not, for example in a @media
block (these will be dealt with later). Browsers may choose not to include @ rules that they do not recognise (initially the spec said to include them, but the authors of the spec have now said not to). They will not include any rules that they do not understand, such as rules using a selector that they do not recognise as being in a valid format. This means that the cssRules collection will almost certainly be a different length in different browsers, and you cannot rely on it being a certain size if you use features that are not supported by all the browsers. Note that although most browsers understand @namespace
rules, they are not part of the specification. Only Mozilla adds these to the cssRules collection, as an unknown rule.
Rules can be added to the collection using the insertRule method of the stylesheet, specifying the text to interpret as a new rule, and the index specifying the rule number that the new rule should be added before. To add a rule at the end, the index should be the number of rules currently in the stylesheet. Rules can be removed using the deleteRule method of the stylesheet, specifying the index of the rule to remove. As always, the index starts at 0 for the first rule.
document.styleSheets[0].deleteRule(1); //delete the second rule
document.styleSheets[0].insertRule('html { color: lime; }',0); //add a new rule at the start
var oLength = document.styleSheets[0].cssRules.length;
document.styleSheets[0].insertRule('body { background: #779; }',oLength); //add a new rule at the end
var oRule = document.styleSheets[0].cssRules[oLength]; //reference the new rule we just added
This part of DOM 2 Style Sheets is one of the most useful and important. Since adding and removing rules is not supported by Safari 2- and Konqueror, and only removing rules is supported by ICEbrowser, they are generally useless for DOM 2 Style Sheets.
Test it here: add the new rule 'p { color: lime; }'
, and then delete it again.
For security reasons, Opera and Mozilla will not allow you to access the cssRules collection of a stylesheet from another domain or protocol. Attempting to access it will throw a security violation error. If your script is likely to encounter a stylesheet like this, you should use a try...catch
structure to prevent your script from halting.
The CSS rule
- Mozilla, Safari/Chrome, Konqueror, Internet Explorer 9+ and ICEbrowser cannot rewrite rules using cssText.
- Internet Explorer 9+ retains unrecognised styles in the cssText, instead of removing them.
- Setting rule cssText will cause Opera 9-9.2 to apply the old version of the rule as well as the new one.
- Safari 2- and Konqueror do not provide cssText for the CSS rule object.
- Safari 2-, Konqueror and ICEbrowser remove any namespace prefix from the selector part of the rule, meaning that it appears to target elements that it does not.
- Safari 2- and ICEbrowser make the selector part of the rule upper case, so it is not valid for XML based documents.
- Safari 2- corrupts ID, attribute, and class selectors beyond recognition, making them invalid and useless.
- ICEbrowser adds wildcards to the selector part of the rule where wildcards are assumed.
- ICEbrowser changes class selectors to
[class~=attribute]
selectors. - The selector part of the rule only includes everything upto the first comma in ICEbrowser.
This is the most fundamental part of DOM 2 Style Sheets; viewing or changing the styles of each rule. Each entry in the stylesheet's cssRules object is a CSS rule. There are several types of rule that may exist in a stylesheet, and the properties they provide will depend on what type of rule they are.
Each rule has a type property, saying what type of rule it is. This will be 1 for normal style rules, 2 for @charset
rules, 3 for @import
rules, 4 for @media
rules, 5 for @font-face
rules, and 6 for @page
rules. If the browser does not ignore unknown @ rules, their type will be 0. CSS rules will also have the parentStyleSheet property, which is a reference to the stylesheet they are inside. Typically, you would need to use the type property to work out what other properties you will be able to access.
The rule also has a cssText property that gives a text representation of the rule. This may have whitespace added or removed, and styles may be split or combined into component styles. Multiple copies of the same style may be replaced with a single copy of the one that is actually used. In most cases, it no longer looks like the rule that was in the original stylesheet, but it should have the same effect in that browser (though not necessarily in other browsers) as the original rule.
var theRule = document.styleSheets[0].cssRules[0];
alert('Type: '+theRule.type+'\nRule: '+theRule.cssText);
Test it here: alert the first rule in the first stylesheet of this page.
In theory it is possible to set the cssText to a new value, as long as the new value can be interpreted as the same type of rule as the original rule (so it is not possible to convert a @import
rule into a @media
rule, for example). Unfortunately, browser support is not good enough to use this at the moment.
document.styleSheets[0].cssRules[0].cssText = 'body { background: #779; }';
If the rule is a @charset
rule, it will have an encoding property, giving the encoding string, which can be rewritten if desired. Unknown @ rules will have no other properties. All other rule types will be covered below:
Normal style, @page, and @font-face rules
- Mozilla does not allow setting of rule selectorText.
- Mozilla splits some valid styles (such as
'padding'
) into several invalid styles (such as'padding-left-value'
and'padding-left-ltr-source: physical;'
). - Mozilla adds a strange
'*|'
namespace prefix to element selectors, but only if there is at least one@import
rule in one of the document's stylesheets, and if there are at least two LINK elements in the document (at least one of which must be a stylesheet). - Opera 10+ does not like having existing style values set to an empty string, and may not update the rendering - set them to an actual value instead.
- Safari 2- corrupts ID, attribute, and class selectors in the selectorText beyond recognition, making it invalid and useless.
- Safari 2- always returns null when using the item method on a rule.
- Safari 2- and Konqueror cannot add, remove or change styles from a rule using the methods of the style object.
- Safari 2-, Konqueror and ICEbrowser cannot rewrite rules using style.cssText.
- Safari 2-, Konqueror and ICEbrowser remove any namespace prefix from the selectorText, meaning that it appears to target elements that it does not.
- Safari 2- and ICEbrowser make selectorText upper case, so it is not valid for XML based documents.
- ICEbrowser cannot change rule styles using
.style.color
syntax. - selectorText only includes everything upto the first comma in ICEbrowser.
- ICEbrowser adds wildcards to the selectorText where wildcards are assumed.
- ICEbrowser changes class selectors to
[class~=attribute]
selectors. - ICEbrowser cannot retrieve values of short form styles like
'margin'
and can only retrieve values for the expanded form'margin-left'
. - ICEbrowser returns all pixel values with a decimal point
'0.0px'
. - ICEbrowser ignores priorities when setting styles.
These are the most common rule types, and the majority of stylesheets contain only normal style rules. The normal style rule and the @page
rule have the selectorText property, which gives the selector text for the rule. This may have whitespace added or removed. In theory, this can be rewritten if desired, but unfortunately, browser support is not good enough to use this at the moment.
document.styleSheets[0].cssRules[7].selectorText = 'div > p';
All three rule types also have a style property. This is the same in functionality as the style property of elements that is normally used for DHTML. However, browsers that support DOM 2 Style Sheets usually implement more of the less well known methods associated with the style object. As well as the usual .style.color
syntax that is well known (and even works in Safari and Konqueror), there are several other ways to access and modify the styles of the rule:
The cssText property gives the text representation of all the styles that the rule contains. This may be reformatted with altered whitespace, may or may not have a final semicolon, and styles may or may not be split or combined. It is possible to set this to a new value, replacing all the original styles with a new set of styles.
document.styleSheets[0].cssRules[7].style.cssText = 'color: lime; font-weight: bold;';
The length property can be used to find how many styles the browser sees, and the item method can be used to retrieve the style names one at a time. The getPropertyValue method retrieves the value of a named style. The getPropertyPriority method retrieves the priority of a named style (typically 'important'). The removeProperty method removes a named style (it will do nothing if the style is not being used). Lastly, the setProperty method creates or rewrites a style. It requires three parameters; the style name, the value, and the priority.
var oStyle = document.styleSheets[0].cssRules[0].style;
oStyle.setProperty('color','lime','');
oStyle.setProperty('font-weight','bold','important');
for( var i = 0, j, s = ''; i < oStyle.length; i++ ) {
j = oStyle.item(i);
s += j + ' = '+oStyle.getPropertyValue(j)+' '+oStyle.getPropertyPriority(j)+'\n';
}
alert(s);
oStyle.removeProperty('color');
oStyle.removeProperty('font-weight');
alert('New content: '+oStyle.cssText);
Test it here: the last rule in the demo stylesheet is currently 'p { }'
. Try running the script shown above on it.
@import rules and imported stylesheets
- Internet Explorer 9+ throws an error if you attempt to access the media attribute of an import rule.
- Safari/Chrome, Konqueror and ICEbrowser actually get this one right. I felt it an important enough event to mention it.
@import
rules are similar to a HTML LINK element, in that they reference a new stylesheet. They have some extra properties that reflect that role.
The href property gives the URL referred to by the import rule. This may be a complete address (typically beginning with 'http://'), or may be the exact URL given by the @import
rule (such as 'imported.css') - this will depend on the browser.
@import
rules can contain a list of media types as well, although this feature is not very often used. As a result, the rule object also has the media property, which behaves exactly like the media property of the StyleSheet.
Most importantly, the rule object also has the styleSheet object. This references the StyleSheet object for the imported stylesheet, and its rules can be referenced and modified in exactly the same way as a normal stylesheet. The imported stylesheet also has the ownerRule property that references the @import rule that imports it.
alert(document.styleSheets[0].cssRules[0].styleSheet.cssRules[0].cssText);
@media blocks
- Safari/Chrome and Konqueror do not provide the parentRule property for rules in a @media block.
- ICEbrowser does not understand media queries but interprets them as a media block with their tokens treated as separate media types.
@media
blocks allow you to target a selection of style rules to a specific set of media types. The @media
rule appears as a single rule in the stylesheet's cssRules collection. The style rules inside it do not appear in the stylesheet's cssRules collection at all. Instead, the rule has its own cssRules collection, that contains all the styles within it. This collection behaves in exactly the same way as the cssRules collection for the StyleSheet object.
The @media
rule also has the insertRule and deleteRule methods, which behave in the same way as those for the StyleSheet object. As the @media
rule also has a list of media types, it also has the media property, which also functions like that of the StyleSheet object.
All rules inside the @media
block also have the parentRule property, which references the @media
rule that they are inside. @media
blocks may contain other @media
blocks, and these can be nested as much as needed. If they are nested, their rules must be accessed by going through the chain of cssRules collections.
alert(document.styleSheets[0].cssRules[0].cssRules[0].cssText);
Test it here: show the contents of the last recognised media block in the first stylesheet.
Getting support for legacy Internet Explorer
Internet Explorer 8- on Windows and Mac does not provide many of the DOM 2 Style Sheets methods or properties, but it has an alternative that is not as complete as the standard, but can handle basic stylesheet manipulation. Internet Explorer 9+ follows the DOM standard only in standards rendering mode. Pages rendered in quirks mode will need to use the Internet Explorer model instead. Pages rendered in IE9+'s IE 7 compatibility mode (enabled automatically or by the user on some pages, or by default for intranet sites) will also not be able to use the standard model. If you need Internet Explorer 8- (or 9+ quirks mode) support, you will have to accept the differences and limitations, make sure your code does not rely on the parts that Internet Explorer is missing, and implement the branching code I will show you here.
In standards rendering mode, Internet Explorer 9+ maintains both the DOM and IE models, which are completely separate. When referencing the same rule using both collections, the returned objects are not the same as each other. The common properties in both models (like selectorText) can hold completely different values, depending on the bugs present in the implementation of that model. This can catch scripts out very easily, so it's best to use the least buggy model - the DOM model.
The styleSheets list
- Internet Explorer on Mac does not populate the list with stylesheets that are added using DOM after the page has loaded.
- The media property is read-only in Internet Explorer on Mac.
- Setting media to
'print'
followed by''
causes Internet Explorer 8- on Windows to start using print media instead of screen media for normal Web page viewing.
Internet Explorer provides the same collection as the other browsers, and to a large extent it works the same way. The type, disabled, href, and title properties all work the same way. The media property is different. Instead of being a media object, it is a string. As a result, there are no methods to add, remove, or list media types. If you want to change it, you will need to treat it as a string. Trying to set it will throw an error in IE Mac, so it will need a try...catch
statement. (Note that in IE 9+ standards mode, IE provides both models - the media attribute follows the standards model.)
var oSheet = document.styleSheets[0];
if( typeof(oSheet.media) == 'string' ) {
try { oSheet.media = 'screen'; } catch(e) {}
} else {
oSheet.media.mediaText = 'screen';
}
Test it here: set the media type on all stylesheets on this page to 'print'
(the page should appear unstyled when viewed normally), use print preview to check if it worked, then return it to normal.
Each stylesheet can reference the element that creates it using owningElement, in the same way as standards compliant browsers use ownerNode.
var oSheet = document.styleSheets[0];
var oElement = oSheet.ownerNode ? oSheet.ownerNode : oSheet.owningElement;
Although IE on Windows provides the styleSheet property of the LINK or STYLE element, in the same way as standards compliant browsers use sheet, this property is not available in IE on Mac.
var oElement = document.getElementsByTagName('style')[0];
var oSheet = oElement.sheet ? oElement.sheet : oElement.styleSheet;
Test it here: check for these properties.
Stylesheet cssRules collection
- Internet Explorer on Mac cannot add or remove rules.
Internet Explorer provides the rules collection, in the same way as standards compliant browsers use cssRules. However, its behaviour is sufficiently different and incompatible, so it is not possible to simply index the same rule in each collection. @page
, @media
, @import
, @charset
, and @font-face
rules are not included in the collection. In IE on Windows, all rules inside a @media
block are included in the rules collection of the stylesheet. In IE Mac, they are ignored completely, and are not available to the DOM. In both browsers, it is not possible to modify the @media
rule itself. Adding new rules into a @media
block is not possible in IE on Windows.
Note that the stylesheet itself has a cssText property in IE, which gives all the CSS in the stylesheet. On Windows, this includes any @media
blocks. However, it is not much fun to edit the stylesheet using pattern matching, which is all that this can provide.
IE on Mac provides both the rules and cssRules collections, but treats them both the IE way (so the cssRules collection is too short). Internet Explorer 9+, also provides both collections in standards rendering mode, but this time, they are implemented completely separately - using the IE and DOM models. In IE 9+, you would almost certainly want to use the standard one where it is available, while IE on Mac would want to use the IE model. If you don't care about IE on Mac (it's been discontinued, so you probably don't care about it), then simply check for the DOM collection and use it where available, falling back to the IE model otherwise:
var oSheet = document.styleSheets[0];
var oRule = oSheet.cssRules ? oSheet.cssRules[7] : oSheet.rules[3];
However, it is possible to get support for IE on Mac. Check if the stadard DOM collection is available, and make sure that it is not the same as the IE collection (that check will also work in other browsers that do not provide the DOM collection, since the IE collection will be undefined):
var oSheet = document.styleSheets[0];
var oRule = ( oSheet.cssRules && oSheet.cssRules != oSheet.rules ) ? oSheet.cssRules[7] : oSheet.rules[3];
Adding and removing rules in Internet Explorer (on Windows) is done using the addRule and removeRule methods. The removeRule method is exactly the same as the standard deleteRule method (except of course that the index will be different). The addRule method, however, is very different to the standard insertRule method. Firstly, it requires two different parameters; the selector string, and the rule string. Secondly, it can only add a rule at the end of the stylesheet.
var oSheet = document.styleSheets[0];
if( oSheet.deleteRule ) {
oSheet.deleteRule(7);
} else if( oSheet.removeRule ) {
oSheet.removeRule(3);
}
if( oSheet.insertRule ) {
oSheet.insertRule('body { background: #779; }',oSheet.cssRules.length);
} else if( oSheet.addRule ) {
oSheet.addRule('body','background: #779;');
}
Test it here: add the new rule 'p { color: lime; }'
, and then delete it again.
The CSS rule
- selectorText only includes everything upto the first comma in IE 8-, and after the last comma in IE 9+.
- selectorText adds wildcards for selectors where wildcards are assumed in IE.
- cssText contains the
{}
braces in IE mac (it also includes them for Element.style.cssText). - The
style.item(0)
method returns'}'
in IE mac if the rule does not have any styles that it recognises. - Elements and style names in selectorText and cssText are upper case in IE (meaning that they are not valid for XML based documents).
- selectorText is read-only in IE Mac.
Since the rules collection only contains normal style rules, the rules do not have a type property. In IE on Windows, they also do not have cssText. They do have a selectorText property though, and (apart from a few bugs) it behaves exactly the same as with standards compliant browsers. Similarly, they also have the parentStyleSheet property.
They also have the all important style property. However, here there are some significant differences. The item method does not exist in IE on Windows. You can try using for(i in styleobject)
but that does not return what you specify in the stylesheet. Instead, it steps through all possible styles that IE recognises, whether you actually used them or not. It is actually a fairly short list (since IE does not actually support very many styles), but it makes recognising your own styles very hard.
More importantly, however, IE does not provide most of the other methods of the style object. To read or change styles, you will have to stick to the .style.color
syntax. Since this works in all browsers, that is not too difficult to work with. Note that IE will throw errors if you set styles to values that it does not support (such as setting display to 'table'). Note that the .style.cssText property is available, but IE Mac makes a bit of a mess of it.
var oSheet = document.styleSheets[0];
var oRule = oSheet.rules ? oSheet.rules[3] : oSheet.cssRules[7];
oRule.style.color = 'lime';
Test it here: the last rule in the demo stylesheet is currently 'p { }'
. Set its color property to 'lime'
, then set it back to ''
.
There is also a StyleSheet.pages collection that gives all @page rules, but it does not give any useful information about the styles in that rule.
@import rules and imported stylesheets
@import
rules are listed in their own StyleSheet.imports collection in IE. Each entry in this collection is a StyleSheet object, that is the same as the styleSheet property of the @import
rule in standards compliant browsers. It has the same properties as a normal stylesheet.
var oSheet = document.styleSheets[0], oImportedSheet;
if( oSheet.imports ) {
oImportedSheet = oSheet.imports[0];
} else {
oImportedSheet = oSheet.cssRules[0].styleSheet;
}
Last modified: 19 March 2011