Question

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;)

Was it helpful?

Solution

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.

OTHER TIPS

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.

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;
}

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;

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

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();
}

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top