8

I've been trying to understanding the way window width is determined and I was wondering if it's different for CSS and jQuery.

If for example I have the CSS media query:

@media (max-width: 979px) {
  /*my css here*/
}

and also some jQuery:

if ($(window).width() < 979) {
  //my jQuery here
}

I would expect the following: - When the browser is resized & refreshed at 980px, both of the above will be ignored - When the browser is resized & refreshed at 978px, both of the above will activate.

However what I'm finding is that - The jQuery and CSS don't kick in until about 964px and below. - Sometimes (if I have window.resize enabled) the jQuery and CSS kick in at seperate widths (a few pixels apart).

Can anyone shed any light on what's going on here?

By the way I'm basing the window width on Firebug's layout viewer.

3
  • I noticed the same problem, none of the solutions reported is working, both return the same value that IS NOT the value that seems to be read by the media query, moreover it's not a jquery related problem since the document/body object contains the same value for style, is there a solution? Commented Oct 24, 2013 at 15:27
  • ok, just found the cause, I added a solution in the answer below. Commented Oct 24, 2013 at 15:41
  • have you tried using body instead of window? Commented Jul 27, 2014 at 12:55

4 Answers 4

8

The problem is related to the scrollbar width: window.innerWidth will return the right value that is read by CSS media queries. Note that $(window).innerWidth() will return the wrong value.

For a cross-browser solution can be used a function like this:

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

var value = viewport().width;
Sign up to request clarification or add additional context in comments.

1 Comment

I swear I've google'd this issue a hundred times and I always forget this solution.
1

A bit off topic, but I assume you're trying to mimic when the javascript fires because you want to do something at the same time as the css breakpoint switches. If you want to have javascript do something when the media query fires, I've found it is easiest to poll for a change created by the css, rather than trying to mimic the way media queries fire (which is inconsistent in browsers due to reporting of scrollbar widths). For instance if at your breakpoint, element-x goes from position: relative to position: fixed, you can ensure your javascript is in line with your css by testing

if(elementX.css('position')== 'fixed'){
//code
}

rather than polling the document width.

1 Comment

I use an invisible ruler element on the page with a max-width value and poll that.
0

Think you might want to use $(document).width() instead

$(window).width(); // returns width of browser viewport
$(document).width(); // returns width of HTML document

http://api.jquery.com/width/

1 Comment

Yeh I tried that and it was returning the same value as the window width for me. Also that doesn't explain why the CSS media queries are kicking in late (according to the width given by firebug)
0

Media queries use the viewport width. I find that getting the html width is much more accurate when trying to match with CSS media queries. Using resize:

$(window).resize(function() {
  if ($('html').width() <= 979) {
    // Do something
  }
});

1 Comment

OK thats cool. But I'm wondering if firebug might be giving an inaccurate body width or if the CSS is reading a different width because it kicks in late. Something to do with the scrollbar maybe?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.