by

Exploring the DOM: Your stylesheets are objects (document.styleSheets)

So, I was helping out a fellow coworker with a JavaScript issue where we were trying to figure out if there was a property somewhere that could tell us what the referring window was. While he was using ‘the googles’, I just pulled up my console window, typed in document, and started browsing through the available properties. Well, Google is faster than scrolling through a console, so the right answer turns out to be document.referrer. But I stumbled upon something else which kind of blew my mind: document.styleSheets. Yeah, your style sheets are in the DOM, and that’s not all…

Pre-requisites

I’m assuming you’re accustomed to working with a decent debugging tool like Chrome’s debugger, FireBug, or Opera’s Dragonfly. I’m also assuming that you have a working knowledge of JavaScript, too.My debugging tool of choice is Google Chrome, so that’s what my steps and screenshots will be. I’m sure if you know your way around one of those other tools you can replicate these steps.

Getting Started with the Console

Hit ctrl + alt + j (cmd + alt + j in Mac) and open up that console. Clear it if you need to with console.clear().

After that, go ahead and type in document.styleSheets.

document.styleSheets is an Array

Once you’ve typed document.styleSheets, the first thing we discover is that it’s an array of objects. In Chrome’s console, I can expand what was returned and see each item in that array is an object called CSSStyleSheet.

document.styleSheets as an array document.styleSheets as an array

The first thing we glean from this is that we’re able to find out how many stylesheets are being used by this document at any given time with the length property: document.styleSheets.length.

The second thing we gather is that this array is constructed in the same order in which they are loaded in the DOM. So if you want to access the second stylesheet, you can do so like you would grab anything else out of an array: document.styleSheets[1].

Accessing a CSSStyleSheet from document.styleSheets Accessing a CSSStyleSheet from document.styleSheets

The properties on the CSSStyleSheet object

So, there’s a few properties on the CSSStyleSheet object that I’ve never seen before. Let’s walk through what we can do with each of these properties:

Disabling a stylesheet instead of removing it

I actually ran into a case, with the very person I was talking to, a few weeks back where a stylesheet was getting added at the application level, instead of the content management system. I wrote a line of jQuery that looked something like this:

$('[href~="blah.css"]').remove()

As it would turn out, there would have been an easier way to do this:

document.styleSheets[1].disabled = true;

You can get the title, but you can’t set it

Maybe you’ll have a different result than I with this, but it looks like you can grab the title of a stylesheet, provided the HTML itself has a title attribute with a value. But you can’t set that title. I imagine this is useful if you need to disable a particular stylesheet programmatically, you can loop through all of the CSSStyleSheets, find the one with the matching title, and disable it.

			<link title="main styles" href="./styles.css" />
var styleTwoTitle = document.styleSheets[1].title;
return styleTwoTitle;
			<link title="main styles" href="./styles.css" />
document.styleSheets[1].title = "Main Styles";
document.styleSheets[1].title //returns null

CSSStyleSheet.title is a getter, not a setter CSSStyleSheet.title is a getter, not a setter

Find out where in the HTML the stylesheet is called

document.styleSheets[1].ownerNode is a pretty handy thing to explore. Granted, this is no different from exploring any other node in the DOM, but I think it’s worthwhile to point out that we can access a list of stylesheets, an individual stylesheet, and the thing that has called the stylesheet. That just seems like a very useful thing to me.

The ownerNode for a CSSStyleSheet Object
The ownerNode for a CSSStyleSheet Object

You can find out if this stylesheet came in as a result of an @import rule

I’m getting ahead of myself, but that parentStyleSheet property is one worthing looking at. If it isn’t null, then it’s an object. That object, is in fact, the CSSStyleSheet object with the @import statement that called this stylesheet.
parentStyleSheet is another CSSStyleSheet object

cssRules proves that JavaScript also rules

This is the big one here: Every rule in your stylesheet is an object. Most of those rules are an object called CSSStyleRule. But, some rules can be a different object called CSSImportRule.

So let’s summarize really quick:

  1. There’s an object that contains all of the stylesheets
  2. Each stylesheet is an object
  3. Every rule in your stylesheet is also an object

So, at this point, we’re looking at document.styleSheets[1].cssRules and discovering that, like Neo, we can now massage the heart of the Matrix.

cssRules is full of CSSStyleRule and much more

You can grap the selector

If you’re looking at a CSSStyleRule object, you’re seeing what I’m seeing. What you’re seeing is that you can actually grap the selector from any given CSSStyleRule. So, it would be insane, but you could loop through the CSSStyleRule objects in the CSSRuleList property, find a given selector, and return those styles.

document.styleSheets[1].rules[14].selectorText // on frankmtaylor.com will return "h2"; 

In conclusion

The stylesheet is not only a member of the DOM, everything on that stylesheet is a member of the DOM, too. That means that you can gather as much about the styles as your heart desires. Crazy.