Discrepancy between CSS and JS media queries?

I’m using CSS media queries for the usual responsive design layout changes, and I want to use JS media queries to decide the size and number of images to download and whether to animate (rotate) them.

It all works as intended when I resize my desktop browser window, but on my Nexus7 tablet the CSS (layout) thinks the screen width is < 600px, but the JS (images) thinks it is > 800px. The actual width is 1200px (portrait mode).

The relevant CSS media query is:

@media only screen and ( max-width: 600px ) {
    nav {
       /* code for nav button which expands when clicked */
    }
} 

And for the JS:

if (matchMedia('only screen and (min-width: 800px)').matches) {
    alert ('more than 800px');
    /* code to select large images */
} else if  (matchMedia('only screen and (min-width: 400px)').matches) {
    alert ('less than 800px');
    /* code to select medium-sized images */
} else {
    alert ('less than 400px');
   /* code to select small images */
}

On my Nexus7 I always get the navigation button (indicating < 600px), but also the alert for ‘more than 800px’. The image actually loaded is the large one (consistent with the screen size as reported by JS).

The site is at: http://holidaymullandiona.com

The layout on the Nexus7 is not quite right yet, but it’s this discrepancy that I’d like to sort out first.

I can’t work out why I’m getting this different behaviour, nor even whether it’s an error in my code or a feature of the two types of media query.

Can anyone help, please ?

So the JavaScript is getting it right and the CSS is getting it wrong.

Does the browser you are using recognise the matchMedia() call directly or is it relying on a polyfill to supply the media test on that platform? If it is relying on the polyfill then possibly the browser doesn’t understand media queries at all and that would explain why it would be getting it wrong with the CSS.

Thanks for your reply.

I prefer the CSS result: otherwise as resolution on small screens increases we’ll end up serving the ‘desktop’ layout to smart phones. What then would be the point of RWD ? I’m also trying to avoid serving multiple large images over the phone network.

No polyfill. I didn’t show it in my post, but the JS media queries are preceded by
if(matchMedia)…
So if the browser didn’t support it I’d have got a different result (or none) and no alerts.

I was using Firefox (on my Nexus7). I changed to Chrome and got a different result. Now the JS query agrees with the CSS, the Alert says ‘less than 800px’, and the medium-sized image is loaded. This is the result I initially expected (and wanted).

So now I know that the two browsers can’t agree. Happy days !

I’ve had the same problem, AFAIK it’s usually caused by scrollbars. Use your browsers developer tools to determine your viewport width, in the meantime check console.log($(window).width()); to determine which one is off. Also read this:
Why is the window.width smaller than the viewport width set in media queries
Cheers!

Thanks for your response.

I thought I was looking at bigger differences than would be caused by the 16 (or thereabouts) pixels devoted to the scroll bar. However, I will investigate and follow up your suggestions.