An explanation

Firefox, Opera and Safari (at least) provide a rule.style.length and an indexor which enables enumerating the styles in a rule. IE6 and 7 do not, however it is not difficult to split the cssText and enumerate through the styles. Firefox (2.0.0.6 at least) seems to have a bug where it breaks on styles like padding and margin. For example, if you have padding: 6px; all the other browsers will return values for padding-top, padding-left, padding-bottom and padding-right. Firefox (at least in this test) returns padding-top and padding-bottom with the correct values, and then padding-right-value, padding-right-ltr-source, padding-right-rtl-source, padding-left-value, padding-left-ltr-source and padding-left-rtl-source, all with undefined values. The same thing happens for margin, and other properties I'm sure. The script includes a work around for this where it checks for style names that end with -value and trims that off and uses that. It then ignores all styles whose values are undefined. This seems to work for all the browsers tested.

The Output

First Style Sheet, First Rule

First Style Sheet, Third Rule

Second Style Sheet, First Rule

Second Style Sheet, Third Rule

The CSS

	<style type='text/css'>
	.rule_0_0 {
		font-family: fantasy;
		font-style: italic;
		font-size: 24px;
		color: red;
		padding: 6px;
	}
	.rule_0_1 {
		padding: 6px;
	}
	.rule_0_2 {
		margin-bottom: 2px;
		margin-right: 2px;
		padding: 6px;
	}
	</style>
	<style type='text/css'>
	.rule_1_0 {
		font-family: fantasy;
		font-style: italic;
		font-size: 24px;
		color: red;
	}
	.rule_1_1 {
		padding: 6px;
	}
	.rule_1_2 {
		margin-bottom: 2px;
		margin-right: 2px;
		padding: 6px;
	}
	</style>
	

The JavaScript

	<script type='text/javascript'>
	function getRule(styleSheetIndex, ruleIndex) {
		var ss = document.styleSheets[styleSheetIndex];
		var rules = ss.rules || ss.cssRules;
		var rule = rules[ruleIndex];
		var res = { selector: rule.selectorText, styles: [] };
		if(Prototype.Browser.IE) {
			var styles = rule.style.cssText.split(";");
			for(var i = 0; i < styles.length; ++i) {
				var style = styles[i].split(":");
				res.styles.push({ name: style[0].strip().toLowerCase(), value: style[1].strip().toLowerCase() });
			}
		} else {
			for(var i = 0; i < rule.style.length; ++i) {
				var name = rule.style[i];
				var value = rule.style[name.camelize()];
				if(name.slice(-6) == "-value") { //Work around for Firefox bug
					name = name.slice(0, -6);
					value = rule.style[name.camelize()];
				}
				if(value) {
					res.styles.push({ name: name, value: value });
				}
			}
		}
		return res;
	}
	function makeRuleOutput(styleSheetIndex, ruleIndex) {
		var rule = getRule(styleSheetIndex, ruleIndex);
		var res = rule.selector + "
"; for(var i = 0; i < rule.styles.length; ++i) { res += (i + 1) + ". " + rule.styles[i].name + ": " + rule.styles[i].value + "
"; } return res } Event.observe(window, "load", function() { document.getElementById("rule_0_0").innerHTML = makeRuleOutput(0, 0); document.getElementById("rule_0_2").innerHTML = makeRuleOutput(0, 2); document.getElementById("rule_1_0").innerHTML = makeRuleOutput(1, 0); document.getElementById("rule_1_2").innerHTML = makeRuleOutput(1, 2); }); </script>