6

I need a quick and dirty way to detect media query support using jquery. I defined a function as follows:

function mediaQueriesEnabled () {
   var v = parseFloat($.browser.version);
   if ($.browser.msie) {
      if (v < 9)
         return (false);
   }
   return (true);
}

Can someone help me fix this up a bit? Looking at this page:

http://caniuse.com/css-mediaqueries

I realized that there are some complexities here. For example, when I test my version of safari, I get "534.57.2". I want to avoid installing modernizr for now, mainly because I'm in a crunch and I need to handle most situations in the short term. Any help is appreciated!

Redtopia
  • 4,947
  • 7
  • 45
  • 68
  • Modernizr is AFAIK the fastest way to go. Just link and test a variable. – John Dvorak Dec 02 '12 at 01:58
  • or you can just kick IE<9 using conditional HTML and assume the rest are good to go. – John Dvorak Dec 02 '12 at 02:00
  • You should definitely use feature detection for this, don't just exclude IE versions less than 9. Also, if you *just* need this feature then please don't use Modernizr; Sandy Gifford's answer works great and is much more lightweight. – Alex W Jun 04 '14 at 14:47
  • I ended up needing modernizr for other things, which what I'm using now. Before that, I used @Niet's answer, which worked great. – Redtopia Jun 04 '14 at 16:28

3 Answers3

14

EDIT: I'm no longer curating this answer as I feel that Niet's is much better (see chosen answer). It should still work, but may need some testing.

Cracking open Modernizr (which can test for media queries) we see it uses the window.matchMedia (MDN page) function. We can check in plain old vanilla JS to see if this function exists:

function mediaQueriesEnabled () {
    if(typeof window.matchMedia != "undefined" || typeof window.msMatchMedia != "undefined") {
        return true;
    } else {
        return false;
    }
}

Or more elegantly:

function mediaQueriesEnabled () {
    return (typeof window.matchMedia != "undefined" || typeof window.msMatchMedia != "undefined");
}

JSFiddle

I've tested in the following browsers that support media queries, all correctly returned true:

  • Safari Mobile
  • Chrome 26

I've tested in the following browsers that do not support media queries, all correctly returned false:

  • IE 7
Sandy Gifford
  • 7,219
  • 3
  • 35
  • 65
  • Good to know... I am definitely leaning towards using a library as I don't think there's any JS standard for this yet. – Redtopia Jun 20 '13 at 01:11
  • 1
    @Redtopia remembering that (A) all libraries are at some point made up of standard JS, and (B) that I'm pretty sure that the code I gave you is fool proof, I'm not quite positive what you mean by no "JS standard" method. I'd be glad to add more detail if it'll help. – Sandy Gifford Jun 20 '13 at 04:12
  • I'm not suggesting that your answer is incorrect. I'm only stating my preference to use a framework for HTML5/CSS3 stuff rather than write pure JS code because it often takes more time to testing various browser support. Frameworks are good, IMHO. Your code may be spot on! I did vote you up for your effort! – Redtopia Jun 21 '13 at 04:57
  • 2
    Thank you =) I'm an old stubborn vanilla JS guy. It's gotten me in deep as often as it has gotten me out. – Sandy Gifford Jun 21 '13 at 16:50
  • Updated based on a small discussion on a very similar answer I gave here: http://stackoverflow.com/questions/11807088/how-can-i-detect-via-javascript-if-browser-supports-css3-media-queries-and-css3/17203057#17203057 – Sandy Gifford Dec 03 '13 at 21:45
  • 1
    This code gives "not supported" for IE9, although it does support media queries. Seems to work fine for other browsers. – user1702401 Mar 31 '15 at 12:36
13

You can create a stylesheet with a media query and see if it works.

In your HTML:

<style>@media all and (min-width:1px) {
    .mediatest {position:absolute}
}</style>

(Or you could dynamically create the stylesheet, but that's harder)

Then in your script:

var d = document.createElement('div');
d.className = "mediatest";
document.body.appendChild(d);
if( window.getComputedStyle && window.getComputedStyle(d).position == "absolute") {
    // supports media queries!
}
document.body.removeChild(d);
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 1
    Just want to throw out there, that although my answer has more votes, if you *can* use this one, use it. It's super fool-proof. If you want a pure, javascript-only solution, by all means use mine; if you're not that crazy, this is what you should be using. – Sandy Gifford Apr 28 '14 at 16:10
0

Here's some working code that is based on @Kolink's answer. So far this code works great... I'll post back to this thread if I have any edits.

The Javascript:

var $globals = {
    mediaQuerySupport: false
}

function initMediaQueries () {
    // tests for media query support
    $globals.mediaQuerySupport = false;
    var d = document.createElement('div');
    d.className = "mediatest"; // found in core.css
    document.body.appendChild(d);
    if( window.getComputedStyle && window.getComputedStyle(d).position == "absolute") {
        $mlGlobals.mediaQuerySupport = true;
        mlDebug ('browser has media query support');
    }
    document.body.removeChild(d);
}

function mediaQueriesEnabled () {
   return ($globals.mediaQuerySupport);
}

$(document).ready(function() {
    initMediaQueries();
    if (mediaQueriesEnabled()) {
        ... do something
    }
});

The CSS (I added this to my main stylesheet file):

@media all and (min-width:1px) {
    .mediatest {position:absolute}
}
Redtopia
  • 4,947
  • 7
  • 45
  • 68