How to conveniently check for responsive breakpoints in JavaScript

by Jens on 10/10/2013

For websites using progressive enhancement or responsive techniques it’s often useful to get track of the viewport-width in JavaScript, e.g. for loading images in different resolutions with ajax. While it’s easy in CSS3 to change styles for different desktop resolutions based on media queries, JavaScript just offers approaches like window.clientWidth() to determine the width. Which doesn’t give you nice “breakpoints” of media queries. To couple JavaScript with CSS3 settings Emil Björklund proposed to use the content element of an :after pseudo-element.

We found this method very helpful and use it in our own application socialfunders.org

How does it work?

You set a tag in the content attribute, which corresponds to the current viewport-width of the browser. Also set the display attribute to none to hide the element. Check the code below to see how to use and implement this on your website.

This is how our settings for the body’s pseudo element look like

body:after {
  content: 'desktop';
  display: none;
}
@media (max-width: 767px) {
  body:after {
    content: 'phone';
  }
}
@media (min-width: 768px) and (max-width: 979px) {
  body:after {
    content: 'tablet';
  }
}
@media (min-width: 1200px) {
  body:after {
    content: 'desktop-large';
  }
}

How to access the element in JavaScript

To easily access the content tag in JavaScript we use a function. Socialfunders.Utils is just our namespace. For your application replace Socialfunders.Utils with your own namespace or just leave out of the namespace.

Socialfunders.Utils.getResponsiveTag = function() {
    var tag = window.getComputedStyle(document.body,':after').getPropertyValue('content');
    tag = tag.replace( /"/g,'');   // Firefox bugfix
    return tag;
};

We also set global ‘constants’ for the tags in case we one day change the names of the tags.

Socialfunders.Utils.PHONE_TAG = "phone";
Socialfunders.Utils.TABLET_TAG = "tablet";
Socialfunders.Utils.DESKTOP_TAG = "desktop";
Socialfunders.Utils.DESKTOP_LARGE_TAG = "desktop-large";

How to use it in your JavaScript code

Here are some examples how to use the code in practice.

if (Socialfunders.Utils.getResponsiveTag() == Socialfunders.Utils.PHONE_TAG) {
    // load low res image
}
if (Socialfunders.Utils.getResponsiveTag() == Socialfunders.Utils.DESKTOP_LARGE_TAG) {
    // load high res image
}

Sources

https://gist.github.com/emilbjorklund/2481019

Social

Discuss this post on Hacker News
Discuss this post on reddit

There are 10 comments in this article:

  1. 10/10/2013Bran van der Meer says:

    I came up with about exactly the same a bit earlier: https://github.com/branneman/css-js-module-states

  2. 10/11/2013Malhotra Sriya says:

    I want to replace ‘Socialfunders.utils’ with ‘Openfunders.utils’ but I now get errors when I try to run this application.

    Please publish the solution to my problem. I have to fix this problem for my very important project today.

  3. 10/11/2013Jannik says:

    @Malhotra Just leave this code “Socialfunders.Utils.” out entirely and you’re good. It’s just needed if you you use namespaces which I assume you don’t.

  4. 10/11/2013Jannik says:

    Important to note that window.matchMedia is also a good option but a little less IE compatible. The method described in this post works for IE9 and above while window.matchMedia works for IE 10 and above https://developer.mozilla.org/en-US/docs/Web/API/Window.matchMedia

  5. 10/18/2013Alex Bell says:

    Awesome. I’ve used similar techniques in the past but this one is beautifully lightweight. The one uncertainty I have is about CSS style resolution and javascript timing. When listening for a resize from one media breakpoint to another, will the pseudo element style on the body always have been consistently applied *before* the listener’s callback executes? Is there any guarantee that the style is applied to the body at the same instant that the resize event fires? Or do you need a short timeout in the callback to be safe?

  6. 10/21/2013Šime Vidas says:

    “…methods like window.clientWidth()…” – clientWidth is a getter property, not a method.

  7. 10/21/2013Jannik says:

    @Šime, “methods” in this case means something like “approaches” or “ways”. Thanks for your hint. Updated the post.

  8. 10/21/2013Советы по использованию media query | Вёрстка, интернет, SEO, WordPress, CSS, HTML5, маркетинг says:

    […] Альтернативная методика, тоже заслуживает изучения. […]

  9. 11/2/2013Tweet Parade (no.44 Okt/Nov 2013) - Best Articles of Last Week | gonzoblog says:

    […] How to conveniently check for responsive breakpoints in JavaScript – For websites using progressive enhancement or responsive techniques it’s often useful to get track of the viewport-width in JavaScript, e.g. for loading images in different resolutions with ajax. […]

  10. 11/11/2013Michael Bianco says:

    There is a library out there that does just this. I’ve used it with some success. https://github.com/14islands/js-breakpoints

Write a comment: