17px difference in the viewport in Mozilla #17

jazz009 opened this Issue Dec 28, 2012 · 14 comments


None yet

4 participants

jazz009 commented Dec 28, 2012

First off all thank you so much for this amazing work. It helps a lot improving my mobile first approach.

I noticed that in Mozilla Firefox, there is a 17px difference between the viewport of a page using response.js and the "real" viewport.

For example if I open the test page (http://responsejs.com/test/) in Mozilla using the adaptive mode (Ctrl + maj + m) and i choose 800 x1280 in the drop down list i will have R.viewportW() 783

After testing a website i'm working on, i found again this 17px difference in the viewport.
I call an image to replace the default text at 641px but the change take place at 658px

The same thing append in IE9, but not in Chrome.

Did you ever noticed something like that, or am I missing something ?

Thank you again for your time

ryanve commented Dec 29, 2012

@jaz009 Sure thing—nice find =] Response currently uses document.documentElement.clientWidth which is the same as jQuery(window).width(). Mozilla adaptive mode seems to use window.innerWidth. Emulators do not necessarily measure the same as an actual device. E.g. compare 320x480 to a real iPhone or to Chrome's emulator in Dev tools » Settings » Overrides. All 3 are different. At first I thought it was just an issue with the emulator but it's in FF in general. I updated the test and you see the issue in FF near the breakpoints.

Response.viewportW() is designed to give the layout viewport. I originally opted to use .clientWidth in Response because it seemed more consistent with browsers, with actual media queries, and with jQuery. To be the most practical matching actual media queries seems paramount. You agree? See this live comparison. I just added the correctedViewportW() technique. It detects which method corresponds to matchMedia.

var correctedViewportW = (function (win, docElem) {

    var mM = win['matchMedia'] || win['msMatchMedia']
      , client = docElem['clientWidth']
      , inner = win['innerWidth']

    return mM && client < inner && true === mM('(min-width:' + inner + 'px)')['matches']
        ? function () { return win['innerWidth'] }
        : function () { return docElem['clientWidth'] }

}(window, document.documentElement));

I'm open to switching .viewportW()/.viewportH() to that effect.

jazz009 commented Dec 30, 2012

Hi Ryan,

Thank you for the quick answer and all the references on your post.

You are right, the main thing for me is to match the actual media queries in order to have a consistent experience
It seems that it's working on the live comparison page, so I would gladly use it.

Now, I don't have your experience on the subject to see if this could have a downside somewhere else...

ryanve commented Jan 2, 2013

@jazz009 Unless someone chimes in here with a reason against it, I'll add the change in the next version ( which should be fairly soon :) Thanks again—I'll let you know when the update is available.

jazz009 commented Jan 7, 2013

Hi Ryan

my pleasure, and thank you for working on this update.

Let me know if I can help you with translation (English/french) or other things on this project.

ryanve commented Jan 8, 2013

@jazz009 I added the viewportW/viewportH fix in 0.7.5 and I'll keep you in mind about translating—that's great. Once #15 is sorted out they'll be updates to the docs. I've been holding off on updating the homepage until then. I'm planning on put the docs on github for group editing.


Was experiencing something like this in 0.6.x — excited to try the fix in the latest response.js. Cheers.


0.7.5 didn’t seem to fully resolve this for me. Is that expected?

ryanve commented Jan 11, 2013

@alanhogan I thought that would fully resolve it at standard zoom. Thanks for the catch. Does it work at standard zoom? It's still just Firefox, right? Please see if you can isolate a discrepency on test/#sets or a circumstance where the "correctedViewportW" looks incorrect on dimensions/#viewport


I was at standard zoom, and yes, as far as I can tell, it was still just Firefox. I’m kind of working on a deadline, and we realized that Firefox isn’t super popular and is just not used on mobile devices, so I’m disabling responsive behavior on Firefox for now. (FYI: I set all my breakpoints to zero for this mode.)


I think the problem is that I was using my own code to set a class on <html> dynamically on crossover and using your R.viewportW() method; I also tried switching to correctedViewportW() as provided above, and I must be doing something wrong, because it didn’t seem to have an effect.

At both of my breakpoints, there are 18 resolutions (the 17px range that was mentioned) that mis-match JS and CSS measurements.

I have a 720px breakpoint; here are the smallest and largest window sizes that exhibit a mis-match:

Screen Shot 2013-01-15 at 8 21 21 PM
Screen Shot 2013-01-15 at 7 11 51 PM

A similar thing happens around my 960px breakpoint:
Screen Shot 2013-01-15 at 8 16 29 PM

Here is the code in question:

Response.addTest("r2012", (function(R) {
  return function(breakpoint) {
    return correctedViewportW() >= r2012BandsHash[breakpoint];
  prefix: "r-",
  prop: "r2012",
  breakpoints: ["mobile", "tablet", "desktop"],
  dynamic: true

Er, I am using Response.band to test if I am in the current band or not, actually, is the code that I’m running to set those classes. I think I added the wrong code up there — that’s just my Response config, obviously.

I’m guessing Response.band hasn’t been updated with the fix, and so my observed behavior would be expected, correct?

ryanve commented Mar 5, 2013

Response.band itself should be fine because is calculated from Response.viewportW rather than remeasured. If it is still inaccurate then it may be an issue Response.viewportW or in the function passed to Response.addTest.

ryanve commented Jan 20, 2014

This was better fixed in 0.7.9 based on information from ryanve/verge#7

@ryanve ryanve closed this Jan 20, 2014
fvpDev commented Feb 19, 2016

Um, just a thought: isn't the 17px difference because of the scrollbar? The difference between browsers is probably due to the different ways the scrollbar is rendered and whether it is considered part of the viewport or not, neh?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment