314

How do I use jQuery to determine the size of the browser viewport, and to redetect this if the page is resized? I need to make an IFRAME size into this space (coming in a little on each margin).

For those who don't know, the browser viewport is not the size of the document/page. It is the visible size of your window before the scroll.

Volomike
  • 23,743
  • 21
  • 113
  • 209
  • Any idea how to get the area that is visible on devices screen, not just what it can scroll to? I see $(window).height() returning the full width of the document, not the portion that is zoomed to. I want to know how much is visible after zoom is applied. – Frank Schwieterman Nov 20 '11 at 02:38
  • http://www.appelsiini.net/projects/viewport This should do it! :) – Mackelito Mar 09 '12 at 14:54
  • 1
    This is not a direct answer to the question, but can be handy for those wanting to manipulate selectors according to their position & visibility relative to the viewport: http://www.appelsiini.net/projects/viewport (plugin) – Wallace Sidhrée Aug 31 '12 at 10:14

7 Answers7

494

To get the width and height of the viewport:

var viewportWidth = $(window).width();
var viewportHeight = $(window).height();

resize event of the page:

$(window).resize(function() {

});
SimaWB
  • 9,246
  • 2
  • 41
  • 46
  • 18
    I tested this on Windows IE6, IE8, FF3.6.3, Google Chrome 5.0.375.70, Opera 10.53, and Safari 5.0 (7533.16). This works consistently on all of these. I also tested FF3.6.3 on Ubuntu and it works there too. I think I'm using jQuery 1.3 with WordPress 2.9.2, which is where I needed this to work. – Volomike Jun 16 '10 at 03:57
  • 48
    Any idea how to get the area that is visible on devices screen, not just what it can scroll to? I see $(window).height() returning the full width of the document, not the portion that is zoomed to. I want to know how much is visible after zoom is applied. – Frank Schwieterman Nov 20 '11 at 02:38
  • 9
    Actually, `innerWidth` / `innerHeight` is more correct to use (covering zooming). –  Jan 16 '13 at 21:03
  • 18
    @FrankSchwieterman Maybe your browser is not behaving the way that you want it to: maybe you are running into this problem: http://stackoverflow.com/q/12103208/923560 . Make sure your HTML file includes a proper `DOCTYPE` declaration , e.g. ` `. – Abdull Feb 15 '13 at 14:59
  • It's important to note these values is very inconsistent across browsers when there is a scroll bar in the element you're measuring. – forsvunnet Nov 22 '14 at 16:59
  • 21
    This is completely wrong. This gives you the size of the document, not the viewport (the size of the window onto the document). –  Nov 30 '14 at 05:43
  • this is the height of the document not the viewport – Toni Leigh May 18 '15 at 12:35
  • 2
    @Mike and @Toni, `$( window ).width()` and `$( window ).height()` return the width and height, respectively, of the viewport. `$( document ).width()` and `$( document ).height()` return the document's measurements. This is according to the jQuery API. – PrinceTyke Jun 29 '15 at 15:19
  • @PrinceTyke Documentation isn't always right. Try it for yourself. –  Jun 30 '15 at 15:00
  • I actually did try it for myself in Firefox 38.0.5 using Firebug and it was accurate, or at least it changed when I resized my window. – PrinceTyke Jun 30 '15 at 17:42
  • 4
    @MikeBethany and ToniLeigh, have you opened the link that Abdull posted above? That will likely solve your problem. – Simon East Jul 07 '15 at 01:39
  • On Safari $(window).height() does not alter with zooming, but it does for Chrome, Firefox and IE. Just something to be aware of. – Rudi Kershaw Jan 12 '16 at 11:59
  • jQuery functions returns value in pixels, can we get view port units using jQuery? – Hasan Baig Jan 01 '19 at 14:44
39

You can try viewport units (CSS3):

div { 
  height: 95vh; 
  width: 95vw; 
}

Browser support

Vitalii Fedorenko
  • 110,878
  • 29
  • 149
  • 111
27

1. Response to the main question

The script $(window).height() does work well (showing the viewport's height and not the document with scrolling height), BUT it needs that you put correctly the doctype tag in your document, for example these doctypes:

For HTML 5:

<!DOCTYPE html>

For transitional HTML4:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Probably the default doctype assumed by some browsers is such, that $(window).height() takes the document's height and not the browser's height. With the doctype specification, it's satisfactorily solved, and I'm pretty sure you peps will avoid the "changing scroll-overflow to hidden and then back", which is, I'm sorry, a bit dirty trick, specially if you don't document it on the code for future programmer's usage.

2. An ADDITIONAL tip, note aside: Moreover, if you are doing a script, you can invent tests to help programmers in using your libraries, let me invent a couple:

$(document).ready(function() {

      if(typeof $=='undefined') {
        alert("PROGRAMMER'S Error: you haven't called JQuery library");
      } else if (typeof $.ui=='undefined') {
        alert("PROGRAMMER'S Error: you haven't installed the UI Jquery library");
      }
      if(document.doctype==null || screen.height < parseInt($(window).height()) ) {
        alert("ERROR, check your doctype, the calculated heights are not what you might expect");
      } 

});


EDIT: about the part 2, "An ADDITIONAL tip, note aside": @Machiel, in yesterday's comment (2014-09-04), was UTTERLY right: the check of the $ can not be inside the ready event of Jquery, because we are, as he pointed out, assuming $ is already defined. THANKS FOR POINTING THAT OUT, and do please the rest of you readers correct this, if you used it in your scripts. My suggestion is: in your libraries put an "install_script()" function which initializes the library (put any reference to $ inside such init function, including the declaration of ready()) and AT THE BEGINNING of such "install_script()" function, check if the $ is defined, but make everything independent of JQuery, so your library can "diagnose itself" when JQuery is not yet defined. I prefer this method rather than forcing the automatic creation of a JQuery bringing it from a CDN. Those are tiny notes aside for helping out other programmers. I think that people who make libraries must be richer in the feedback to potential programmer's mistakes. For example, Google Apis need an aside manual to understand the error messages. That's absurd, to need external documentation for some tiny mistakes that don't need you to go and search a manual or a specification. The library must be SELF-DOCUMENTED. I write code even taking care of the mistakes I might commit even six months from now, and it still tries to be a clean and not-repetitive code, already-written-to-prevent-future-developer-mistakes.

gdoron
  • 147,333
  • 58
  • 291
  • 367
David L
  • 1,058
  • 12
  • 9
  • 2
    It is very hard to read your post. Please redo your post so that you get used to the [StackExchange Markdown](http://stackoverflow.com/editing-help) like everyone else. There's [a reason why StackExchange sites do not use TinyMCE](http://meta.stackexchange.com/questions/28351/why-doesnt-the-site-use-a-rich-text-editor), but if you have a gripe with it, get involved in the [Meta](http://meta.stackoverflow.com/). – Volomike Mar 12 '14 at 13:58
  • It's a bit weird that you check for the availability of `$` after you already used the `$` to call `$(document).ready(function() { } );`. It's good if you check if jQuery is available, but at this point it's too late already. – Machiel Sep 03 '14 at 17:20
  • @Machiel, you are UTTERLY RIGHT. Fortunately I just went to check my scripts, and they don't use the ready event. Yes, thanks, I felt stupid when you said this, but fortunately I've just checked that in my scripts the checking is inside a function called "install_this_script()", and in such installation I call the init function of the library, but before that, I check (OUTSIDE JQUERY) if the $ object is defined or not. THANKS ANYWAY, bro, you really freaked me out! I'm afraid this post was here too long, I hope this mistake hasn't done a lot of harm to the other readers. I corrected the post. – David L Sep 05 '14 at 17:30
  • This should be the real answer! Thanks! – Justin T. Watts Jan 08 '16 at 22:24
6

You can use $(window).resize() to detect if the viewport is resized.

jQuery does not have any function to consistently detect the correctly width and height of the viewport[1] when there is a scroll bar present.

I found a solution that uses the Modernizr library and specifically the mq function which opens media queries for javascript.

Here is my solution:

// A function for detecting the viewport minimum width.
// You could use a similar function for minimum height if you wish.
var min_width;
if (Modernizr.mq('(min-width: 0px)')) {
    // Browsers that support media queries
    min_width = function (width) {
        return Modernizr.mq('(min-width: ' + width + ')');
    };
}
else {
    // Fallback for browsers that does not support media queries
    min_width = function (width) {
        return $(window).width() >= width;
    };
}

var resize = function() {
    if (min_width('768px')) {
        // Do some magic
    }
};

$(window).resize(resize);
resize();

My answer will probably not help resizing a iframe to 100% viewport width with a margin on each side, but I hope it will provide solace for webdevelopers frustrated with browser incoherence of javascript viewport width and height calculation.

Maybe this could help with regards to the iframe:

$('iframe').css('width', '100%').wrap('<div style="margin:2em"></div>');

[1] You can use $(window).width() and $(window).height() to get a number which will be correct in some browsers, but incorrect in others. In those browsers you can try to use window.innerWidth and window.innerHeight to get the correct width and height, but i would advice against this method because it would rely on user agent sniffing.

Usually the different browsers are inconsistent about whether or not they include the scrollbar as part of the window width and height.

Note: Both $(window).width() and window.innerWidth vary between operating systems using the same browser. See: https://github.com/eddiemachado/bones/issues/468#issuecomment-23626238

forsvunnet
  • 1,238
  • 10
  • 17
4
function showViewPortSize(display) {
    if (display) {
        var height = window.innerHeight;
        var width = window.innerWidth;
        jQuery('body')
            .prepend('<div id="viewportsize" style="z-index:9999;position:fixed;bottom:0px;left:0px;color:#fff;background:#000;padding:10px">Height: ' + height + '<br>Width: ' + width + '</div>');
        jQuery(window)
            .resize(function() {
                height = window.innerHeight;
                width = window.innerWidth;
                jQuery('#viewportsize')
                    .html('Height: ' + height + '<br>Width: ' + width);
            });
    }
}
$(document)
    .ready(function() {
        showViewPortSize(true);
    });
AnuRaj
  • 78
  • 7
  • Using $(window).height() will not give you the viewport size it will give you the size of the entire window, which is usually the size of the entire document though the document could be even larger. – AnuRaj Jun 10 '16 at 10:26
  • great for width ! – Marc Oct 13 '16 at 15:33
2

To get size of viewport on load and on resize (based on SimaWB response):

function getViewport() {
    var viewportWidth = $(window).width();
    var viewportHeight = $(window).height();
    $('#viewport').html('Viewport: '+viewportWidth+' x '+viewportHeight+' px');
}

getViewport();

$(window).resize(function() {
    getViewport()
});
SandroMarques
  • 6,070
  • 1
  • 41
  • 46
1

Please note that CSS3 viewport units (vh,vw) wouldn't play well on iOS When you scroll the page, viewport size is somehow recalculated and your size of element which uses viewport units also increases. So, actually some javascript is required.

D.A.H
  • 858
  • 2
  • 9
  • 19