Save Expand icon

Ron Valstar
front-end developer

DRY responsive JavaScript

My last post got me thinking when I was implementing responsive JavaScript events (well, signals really). I never liked it when similar things are defined or implemented multiple times. That is the reason why I tend to put classNames added through JavaScript inside a value object, or why I wrote something to parse Less variables to JavaScript. Long live DRY!

So why define your responsive breakpoints in JavaScript when they are already defined in your CSS? You’ll have to search a little since they are neatly tucked away inside your document.styleSheets object, but they are right there!

The document.styleSheets object is structured like this:

document.styleSheets {StyleSheetList}
 |-[0] {CSSStyleSheet}
 |  |-cssRules {CSSRuleList}
 |  |  |-[0] {CSSRule}

CSSRule is an interface, so inside that CSSRuleList we can also find the CSSMediaRule (its type is CSSRule.MEDIA_RULE).

The actual media queries are in CSSMediaRule.media{MediaList}.
Unless your name is IE, then you’ll say you put stuff in your list but it’s really empty.

The only tricky part is how to interpret this media query data correctly since the notation can vary quite a lot (although in practice only a limited amount of variations is used).
I’ve checked the possibilities described at at W3C and decided that (for now) it’s safe enough to check on min- and max-width.

This responsive JavaScript is really nothing more than a proof of concept. I haven’t done any exhaustive testing other than see it working on the four most common browsers.

A small sidenote about when the script should kick in. In practise DOMContentLoaded fires when the stylesheets are loaded, provided the script tag is after the link tag (for Webkit and Mozilla). In theory however, it shouldn’t. So we’re safer to use the good old Window load event here.