Get the browser viewport dimensions with JavaScript

Get the browser viewport dimensions with JavaScript

I want to provide my visitors the ability to see images in high quality, is there any way I can detect the window size?
Or better yet, the viewport size of the browser with JavaScript? See green area here:

Solutions/Answers:

Solution 1:

Cross-browser @media (width) and @media (height) values 

var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

window.innerWidth and .innerHeight

  • gets CSS viewport @media (width) and @media (height) which include scrollbars
  • initial-scale and zoom variations may cause mobile values to wrongly scale down to what PPK calls the visual viewport and be smaller than the @media values
  • zoom may cause values to be 1px off due to native rounding
  • undefined in IE8-

document.documentElement.clientWidth and .clientHeight

Resources

Solution 2:

jQuery dimension functions

$(window).width() and $(window).height()

Solution 3:

You can use the window.innerWidth and window.innerHeight properties.

innerHeight vs outerHeight

Solution 4:

If you aren’t using jQuery, it gets ugly. Here’s a snippet that should work on all new browsers. The behavior is different in Quirks mode and standards mode in IE. This takes care of it.

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;

Solution 5:

I was able to find a definitive answer in JavaScript: The Definitive Guide, 6th Edition by O’Reilly, p. 391:

This solution works even in Quirks mode, while ryanve and ScottEvernden’s current solution do not.

function getViewportSize(w) {

    // Use the specified window or the current window if no argument
    w = w || window;

    // This works for all browsers except IE8 and before
    if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };

    // For IE (or any browser) in Standards mode
    var d = w.document;
    if (document.compatMode == "CSS1Compat")
        return { w: d.documentElement.clientWidth,
           h: d.documentElement.clientHeight };

    // For browsers in Quirks mode
    return { w: d.body.clientWidth, h: d.body.clientHeight };

}

except for the fact that I wonder why the line if (document.compatMode == "CSS1Compat") is not if (d.compatMode == "CSS1Compat"), everything looks good.

Solution 6:

I know this has an acceptable answer, but I ran into a situation where clientWidth didn’t work, as iPhone (at least mine) returned 980, not 320, so I used window.screen.width. I was working on existing site, being made “responsive” and needed to force larger browsers to use a different meta-viewport.

Hope this helps someone, it may not be perfect, but it works in my testing on iOs and Android.

//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width 
  //first see if they have window.screen.width avail
  (function() {
    if (window.screen.width)
    {
      var setViewport = {
        //smaller devices
        phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
        //bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints  
        other: 'width=1045,user-scalable=yes',
        //current browser width
        widthDevice: window.screen.width,
        //your css breakpoint for mobile, etc. non-mobile first
        widthMin: 560,
        //add the tag based on above vars and environment 
        setMeta: function () {
          var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other; 
          var head = document.getElementsByTagName("head")[0];
          var viewport = document.createElement('meta');
          viewport.setAttribute('name','viewport');
          viewport.setAttribute('content',params);
          head.appendChild(viewport);
        }
      }
      //call it 
      setViewport.setMeta();
    }
  }).call(this);