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
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
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.
var styleTwoTitle = document.styleSheets[1].title; return styleTwoTitle;
document.styleSheets[1].title = "Main Styles"; document.styleSheets[1].title //returns null
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.
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.
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:
- There’s an object that contains all of the stylesheets
- Each stylesheet is an object
- 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.
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.