The property document.styleSheets[0].cssRules is a CSSRuleList (apart from in IE6-8, where you should styleSheets[0].rules for the css rules and styleSheets[0].imports for the imports). This CSSRuleList has a certain number of CSSRules in the list. These rules can be of different types. For instance a @import CSSRule implements the CSSImportRule interface and a 'normal' style declaration CSSRule implements the CSSStyleRule interface.
We can detect if a CSSRule is a @import css rule, by checking if rule.type == IMPORT_RULE
, where IMPORT_RULE is 3. If it is a CSSImportRule, we can obtain its styleSheet property to obtain the css rules in the imported stylesheet and repeat the process described above.
The parsable textual representation of any CSSRule can be obtained by obtaining the cssText property: rule.cssText
. In Internet Explorer 6-8 however, we have to use rule.style.cssText
.
In other words, we can obtain all CSSRule's in the stylesheets (including its imports) using the following code. I've also put a working sample into a jsfiddle. Note that this code does not work in IE6-8. For this solution I suggest you to check my solution for another problem on SO here.
/**
* Get the css rules of a stylesheet which apply to the htmlNode. Meaning its class
* its id and its tag.
* @param CSSStyleSheet styleSheet
*/
function getCssRules(styleSheet) {
if ( !styleSheet )
return null;
var cssRules = new Array();
if (styleSheet.cssRules) {
var currentCssRules = styleSheet.cssRules;
// Import statement are always at the top of the css file.
for ( var i = 0; i < currentCssRules.length; i++ ) {
// cssRules contains the import statements.
// check if the rule is an import rule.
if ( currentCssRules[i].type == 3 ) {
// import the rules from the imported css file.
var importCssRules = getCssRules(currentCssRules[i].styleSheet);
if ( importCssRules != null ) {
// Add the rules from the import css file to the list of css rules.
cssRules = addToArray(cssRules, importCssRules);
}
// Remove the import css rule from the css rules.
styleSheet.deleteRule(i);
}
else {
// We found a rule that is not an CSSImportRule
break;
}
}
// After adding the import rules (lower priority than those in the current stylesheet),
// add the rules in the current stylesheet.
cssRules = addToArray(cssRules, currentCssRules);
}
return cssRules;
}
/**
* Since a list of rules is returned, we cannot use concat.
* Just use old good push....
* @param CSSRuleList cssRules
* @param CSSRuleList cssRules
*/
function addToArray(cssRules, newRules) {
for ( var i = 0; i < newRules.length; i++ ) {
cssRules.push(newRules[i]);
}
return cssRules;
}
/**
* Finds all CSS rules.
*/
function getCSSRules() {
var cssRules = new Array();
// Loop through the stylesheets in the html document.
for ( var i = 0; i < document.styleSheets.length; i++ ) {
var currentCssRules = getCssRules(document.styleSheets[i])
if ( currentCssRules != null )
cssRules.push.apply(cssRules, currentCssRules);
}
return cssRules;
}
// An array of all CSSRules.
var allCSSRules = getCSSRules();
for ( var i = 0; i < allCSSRules.length; i++ ) {
console.log(allCSSRules[i].cssText);
}