18

How do I detect the width of a user's window with Javascript and account for their scrollbar? (I need the width of the screen INSIDE of the scrollbar). Here's what I have...it seems to work in multiple browsers...except that it doesn't account for the scrollbars..

    function browserWidth() {
  var myWidth = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
  } else if( document.documentElement && document.documentElement.clientWidth ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
  } else if( document.body && document.body.clientWidth ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
  }
  return myWidth;
}

any ideas? i need it to work in all browsers;)

johnnietheblack
  • 13,050
  • 28
  • 95
  • 133

7 Answers7

7

A (markedly nasty) workaround if you're only interested in the width is to create a 1px x 100% div and use its offsetWidth. Works on IE>=7, FF, Chrome, Safari and Opera (I've not tried IE6, as we're working to a you're-lucky-it-works-at-all-so-don't-complain-about-rendering-oddities policy thereabouts these days). I hang the div off document.body with attributes { position: 'absolute', top: '-1px', left: 0, width: '100%', height: '1px' }, creating it the first time it's needed.

Works if you can stomach it.

Pete Jordan
  • 558
  • 4
  • 2
5

You will find the big summary of what properties are supported on what browsers on this page on quirksmode.org.

Your best bet is probably to grab an element in the page (using document.body where supported, or document.getElementById or whatever), walk its offsetParent chain to find the topmost element, then examine that element's clientWidth and clientHeight.

moonshadow
  • 86,889
  • 7
  • 82
  • 122
  • This answer is wrong as it will fails if the topmost element is set to a different size than the window, for example if the body has content stretching it beyond the 100% (like most pages). – Lior Feb 04 '14 at 10:09
3

This is a more efficient version of an idea posted here by Tim Salai ( even though you are just beginning, it was brilliant to place an element in the bottom right corner like that ).

var getDimensions = document.createElement("div");
getDimensions.setAttribute("style", 
            "visibility:hidden;position:fixed;bottom:0px;right:0px;");
document.getElementsByTagName("body")[0].appendChild(getDimensions);
var viewportWidth = getDimensions.offsetLeft;
var viewportHeight = getDimensions.offsetTop;

And here is a modular version

var PageDimensions = function(){
 var Width;
 var Height;     

 function pagedimensionsCtor (){
   var getDimensions = document.createElement("div");
   getDimensions.setAttribute("style" , 
         "visibility:hidden;position:fixed;bottom:0px;right:0px;");
   document.getElementsByTagName("body")[0].appendChild(getDimensions);
   Width = getDimensions.offsetLeft;
   Height = getDimensions.offsetTop;
   getDimensions.parentNode.removeChild(getDimensions);
 }
 pagedimensionsCtor();

 function Reset(){
  pagedimensionsCtor();
 }     

 function GetPageHeight(){
  return Height;
 }

 function GetPageWidth(){
  return Width;
 }

 return{
  Reset: Reset,
  GetPageHeight: GetPageHeight,
  GetPageWidth: GetPageWidth
 };
}

Use the modular version:

var page = new PageDimensions();
console.log("viewportWidth: " + page.GetPageWidth() + " viewportHeight: " + page.GetPageHeight());

Bonus feature:

page.Reset();//just in case you think your dimensions have changed
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • I think you actually need to return `Height` and `Width` instead of `Height()` and `Width()` in your `GetPageHeight` and `GetPageWidth` functions. Also, your example usage has `GetWidth()` and `GetHeight()`, which should be `GetPageWidth()` and GetPageHeight()`. – cjbarth Jan 18 '13 at 18:19
  • The reason I said about the return is that I tried the code your way and it didn't work. After I changed `Height()` and `Width()` to `Height` and `Width` it worked. (Silly me though, I resized my main page `DIV` and forgot that I had a border on my `DIV`, so I had to do some extra math for that.) – cjbarth Jan 18 '13 at 18:43
3

Just add that before the window.innerWidth() check:

if (typeof(document.body.clientWidth) == 'number') {
    // newest gen browsers
    width = document.body.clientWidth;
    height = document.body.clientHeight;
}
mst
  • 39
  • 1
  • If the width of the body is bigger than the window (i.e. there is a horizontal scrollbar present), this will give the *body*'s width rather than the window's – Himanshu P Nov 12 '13 at 09:03
3

This is what I did - only half a year into learning JavaScript, so this may be a bad fix. First, I created a transparent square image (10px x 10px), but you could also create a non-transparent image and add this to your JavaScript as
document.getElementById('getDimensions').style.visibility = "hidden";

HTML:

<img id="getDimensions" src="images/aSmallBox.png" alt="A small transparent image  
meant to determine the dimensions of the viewport" width="10px" height="10px"/>

JavaScript:

//Inside function called by window.onload event handler (could go in CSS file, but   
//better to keep it with other related code in JS file)
document.getElementById('getDimensions').style.position = "fixed";
document.getElementById('getDimensions').style.bottom = "0px";
document.getElementById('getDimensions').style.right = "0px";   

//Everything below inside function called by window.onresize event handler
var baseWidthCalculation = document.getElementById('getDimensions').offsetLeft;
var baseHeightCalculation = document.getElementById('getDimensions').offsetTop;
  //Account for the dimensions of the square img element (10x10)
var viewportWidth = baseWidthCalculation + 10;
var viewportHeight = baseHeightCalculation + 10;
Prasad Jadhav
  • 5,090
  • 16
  • 62
  • 80
Tim Salai
  • 31
  • 2
0

I would compare the "innerWidth" to the width of the body. If the body width > innerwidth, then scrollbars are present.

if (browserWidth() < document.body.offsetWidth) {
  doSomething();
}
TJ L
  • 23,914
  • 7
  • 59
  • 77
  • hmmm cool...i guess im at a loss of WHAT to do when i figure out if scrollbars are present...since browsers have different sized scrollbars...ideas? – johnnietheblack Feb 27 '09 at 19:04
  • 1
    @johnintheblack: Please take note that in windows, changing the windows theme causes the scrollbars to chagne width, so this needs to be taken into account when testing. The vista default theme's width is 8 pixels larger than the default theme for xp, for example. – diadem Feb 19 '10 at 21:37
0

Another solution you can try is changing some CSS so scrolling happens within your page, instead of the browser window doing it. In the style for body, add overflow:auto. Now the body element includes the scrollbar, so when you get the window width you're measuring the width outside the scrolling container instead of inside it.

This does feel like a potential source of quirkiness, and possibly an accessibility issue, so if you're going for widespread use you might want to test it quite carefully.

Dylan McCall
  • 233
  • 1
  • 2
  • 10