Mozilla

Using window.matchMedia to do media queries in JavaScript

For people building web sites, Responsive Web Design has become a natural approach to making sure the content is available for as many users as possible. This is usually attended to via CSS media queries. However, there is a JavaScript alternative as well.

Introducing window.matchMedia

The way to approach media queries in JavaScript is through window.matchMedia. Basically, you just use the same approach as with CSS, but with a JavaScript call:

var widthQuery = window.matchMedia("(min-width: 600px)");

This query returns a MediaQueryList object, on which you can do a few things:

matches
Boolean whether the query matched or not.
media
Serialized media query list.
addListener
Adding event listener to a media query. Much preferred over polling values or similar.
removeListener
Removing event listener from a media query.

Therefore, the easy way to determine if a media query matched is using the matches property:

var widthMatch = window.matchMedia("(min-height: 500px)").matches;

Adding listeners is very easy:

function getOrientationValue (mediaQueryList) {
    console.log(mediaQueryList.matches);
}
 
portraitOrientationCheck = window.matchMedia("(orientation: portrait)");
portraitOrientationCheck.addListener(getOrientationValue);

Demo and code

I’ve put together a window.matchMedia demo where you can see some queries in action. Try resizing the window and see the values change.

The complete JavaScript code for that demo, which is of course available on GitHub, is as follows:

Web browser support

At this time, window.matchMedia has been implemented in:

  • Firefox 6+
  • Google Chrome 9+
  • Safari 5.1+. Note: doesn’t support addListener.
  • Firefox mobile
  • Google Chrome beta on Android. Note: doesn’t support addListener.
  • Safari 5 on iOS. Note: doesn’t support addListener.
  • Android stock browser. Note: doesn’t support addListener.

It is also planned to be in Internet Explorer 10.

For older/unsupported web browsers, you can try the matchMedia() polyfill, although it doesn’t support addListener.

15 comments

Comments are now closed.

  1. Moldován Eduárd wrote on June 5th, 2012 at 06:34:

    Oh boy, this looks great. I’ll give it a try shortly.

    1. Robert Nyman wrote on June 6th, 2012 at 23:06:

      Cool! Hope it’s useful for you!

  2. d7ke wrote on June 5th, 2012 at 13:45:

    This looks pretty powerful.

    1. Robert Nyman wrote on June 6th, 2012 at 23:06:

      I think so too – a nice complement to media queries in CSS.

  3. John A. Bilicki III wrote on June 7th, 2012 at 06:30:

    Never EVER use the proprietary Microsoft JScript innerHTML method (or related methods) as they do not correctly register nodes in the DOM. To set the text for a node use nodeValue. Examples…

    document.getElementById(‘example-span’).nodeValue = ‘awesome’;

    document.getElementById(‘example-div’).firstChild.nodeValue = ‘awesome’;

    …and even if someone somehow slipped it in to any given standard it does not negate that it’s horribly unreliable to use.

    1. Robert Nyman wrote on June 7th, 2012 at 10:44:

      I don’t necessarily agree with you. It depends on the situation and what you want to do. I wrote about this together with Anne van Kesteren of Opera a long time ago.

      So, yes, there could be potential risks with it, but I don’t personally think it rules out all usages of it.

  4. John A. Bilicki III wrote on June 7th, 2012 at 11:30:

    Robert, what people don’t realize is that it does not actually register the DOM correctly. Try giving focus to an ID loaded via AJAX after the last readyState has closed and them dumped in to the DOM via innerHTML, won’t happen and it’s not limited to giving elements focus either. If adding (X)HTML to the DOM is the equivalent to crowning royalty innerHTML takes the crown and chucks it at the person’s head.

    1. Robert Nyman wrote on June 7th, 2012 at 11:52:

      I’m aware of some of the issues with it, but I don’t think that renders it useless for all cases.

      1. John A. Bilicki III wrote on June 7th, 2012 at 12:08:

        The only instance I ever found it useful for was read-only to look at XHTML directly though now we have Firebug and even without Firebug you can serialize XHTML…

        var c = document.getElementById(‘target_element’).cloneNode(true);
        var s = new XMLSerializer();
        var str = s.serializeToString(c);
        alert(str);

        So read-only would be the at-best for quick debugging though I could never agree to any write operations. Beyond that we will have to agree to disagree. Besides that good article, new code is useless without a good demo that explains not only how to use it though how it can be useful.

        1. Robert Nyman wrote on June 8th, 2012 at 02:02:

          Yes, we’ll agree to disagree then. :-)
          And thanks, glad you liked the article!

  5. rdeck wrote on July 17th, 2012 at 03:15:

    I will put into practice this week end!

    1. Robert Nyman wrote on July 31st, 2012 at 08:36:

      Hope it proved useful!

  6. Alon wrote on November 8th, 2012 at 02:38:

    Thank you so much !!
    was looking for this

  7. Mat wrote on February 2nd, 2013 at 12:39:

    Approach is spelt incorrectly in the sentence “The way to approch media queries in JavaScript”. It’s funny because you spelt it correctly on the following line. Great article very useful!

    1. Robert Nyman [Editor] wrote on February 4th, 2013 at 03:02:

      Thanks! Just a little typo.

Comments are closed for this article.