[javascript] How can I get the browser's scrollbar sizes?

How can I determine the height of a horizontal scrollbar, or the width of a vertical one, in JavaScript?

This question is related to javascript scrollbar

The answer is


Using jQuery, you can shorten Matthew Vines answer to:

function getScrollBarWidth () {
    var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
        widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
    $outer.remove();
    return 100 - widthWithScroll;
};

window.scrollBarWidth = function() {
  document.body.style.overflow = 'hidden'; 
  var width = document.body.clientWidth;
  document.body.style.overflow = 'scroll'; 
  width -= document.body.clientWidth; 
  if(!width) width = document.body.offsetWidth - document.body.clientWidth;
  document.body.style.overflow = ''; 
  return width; 
} 

This is only script I've found, which is working in webkit browsers ... :)

$.scrollbarWidth = function() {
  var parent, child, width;

  if(width===undefined) {
    parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');
    child=parent.children();
    width=child.innerWidth()-child.height(99).innerWidth();
    parent.remove();
  }

 return width;
};

Minimized version:

$.scrollbarWidth=function(){var a,b,c;if(c===undefined){a=$('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');b=a.children();c=b.innerWidth()-b.height(99).innerWidth();a.remove()}return c};

And you have to call it when document is ready ... so

$(function(){ console.log($.scrollbarWidth()); });

Tested 2012-03-28 on Windows 7 in latest FF, Chrome, IE & Safari and 100% working.

source: http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth


Here's the more concise and easy to read solution based on offset width difference:

function getScrollbarWidth(): number {

  // Creating invisible container
  const outer = document.createElement('div');
  outer.style.visibility = 'hidden';
  outer.style.overflow = 'scroll'; // forcing scrollbar to appear
  outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
  document.body.appendChild(outer);

  // Creating inner element and placing it in the container
  const inner = document.createElement('div');
  outer.appendChild(inner);

  // Calculating difference between container's full width and the child width
  const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);

  // Removing temporary elements from the DOM
  outer.parentNode.removeChild(outer);

  return scrollbarWidth;

}

See the JSFiddle.


detectScrollbarWidthHeight: function() {
    var div = document.createElement("div");
    div.style.overflow = "scroll";
    div.style.visibility = "hidden";
    div.style.position = 'absolute';
    div.style.width = '100px';
    div.style.height = '100px';
    document.body.appendChild(div);

    return {
        width: div.offsetWidth - div.clientWidth,
        height: div.offsetHeight - div.clientHeight
    };
},

Tested in Chrome, FF, IE8, IE11.


Create an empty div and make sure it's present on all pages (i.e. by putting it in the header template).

Give it this styling:

#scrollbar-helper {
    // Hide it beyond the borders of the browser
    position: absolute;
    top: -100%;

    // Make sure the scrollbar is always visible
    overflow: scroll;
}

Then simply check for the size of #scrollbar-helper with Javascript:

var scrollbarWidth = document.getElementById('scrollbar-helper').offsetWidth;
var scrollbarHeight = document.getElementById('scrollbar-helper').offsetHeight;

No need to calculate anything, as this div will always have the width and height of the scrollbar.

The only downside is that there will be an empty div in your templates.. But on the other hand, your Javascript files will be cleaner, as this only takes 1 or 2 lines of code.


This should do the trick, no?

function getScrollbarWidth() {
  return (window.innerWidth - document.documentElement.clientWidth);
}

Already coded in my library so here it is:

var vScrollWidth = window.screen.width - window.document.documentElement.clientWidth;

I should mention that jQuery $(window).width() can also be used instead of window.document.documentElement.clientWidth.

It doesn't work if you open developer tools in firefox on the right but it overcomes it if the devs window is opened at bottom!

window.screen is supported quirksmode.org!

Have fun!


I made an updated version of @Matthew Vines answer.

It's easier to read, easier to understand. It doesn't require an inner element. The element created to get the scroll bar width has a 100% height/width so it doesn't create any visible scroll bar on the body on lower end PCs/mobiles which could take a bit more time to create the element, get the widths, and finally remove the element.

const getScrollBarWidth = () => {
  const e = document.createElement('div');
  Object.assign(e.style, {
    width: '100%',
    height: '100%',
    overflow: 'scroll',
    position: 'absolute',
    visibility: 'hidden',
    top: '0',
    left: '0',
  });

  document.body.appendChild(e);

  const scrollbarWidth = e.offsetWidth - e.clientWidth;

  document.body.removeChild(e);

  return scrollbarWidth;
};

console.log(getScrollBarWidth());

I do recommend to check for the scroll bar width only once, at page load (except if it doesn't fit your needs) then store the result in a state/variable.


It seems to work, but maybe there is a simpler solution that works in all browsers?

_x000D_
_x000D_
// Create the measurement node_x000D_
var scrollDiv = document.createElement("div");_x000D_
scrollDiv.className = "scrollbar-measure";_x000D_
document.body.appendChild(scrollDiv);_x000D_
_x000D_
// Get the scrollbar width_x000D_
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;_x000D_
console.info(scrollbarWidth); // Mac:  15_x000D_
_x000D_
// Delete the DIV _x000D_
document.body.removeChild(scrollDiv);
_x000D_
.scrollbar-measure {_x000D_
 width: 100px;_x000D_
 height: 100px;_x000D_
 overflow: scroll;_x000D_
 position: absolute;_x000D_
 top: -9999px;_x000D_
}
_x000D_
_x000D_
_x000D_


I found a simple solution that works for elements inside of the page, instead of the page itself: $('#element')[0].offsetHeight - $('#element')[0].clientHeight

This returns the height of the x-axis scrollbar.


The way Antiscroll.js does it in it's code is:

function scrollbarSize () {
  var div = $(
      '<div class="antiscroll-inner" style="width:50px;height:50px;overflow-y:scroll;'
    + 'position:absolute;top:-200px;left:-200px;"><div style="height:100px;width:100%"/>'
    + '</div>'
  );

  $('body').append(div);
  var w1 = $(div).innerWidth();
  var w2 = $('div', div).innerWidth();
  $(div).remove();

  return w1 - w2;
};

The code is from here: https://github.com/LearnBoost/antiscroll/blob/master/antiscroll.js#L447


From David Walsh's blog:

_x000D_
_x000D_
// Create the measurement node_x000D_
var scrollDiv = document.createElement("div");_x000D_
scrollDiv.className = "scrollbar-measure";_x000D_
document.body.appendChild(scrollDiv);_x000D_
_x000D_
// Get the scrollbar width_x000D_
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;_x000D_
console.info(scrollbarWidth); // Mac:  15_x000D_
_x000D_
// Delete the DIV _x000D_
document.body.removeChild(scrollDiv);
_x000D_
.scrollbar-measure {_x000D_
 width: 100px;_x000D_
 height: 100px;_x000D_
 overflow: scroll;_x000D_
 position: absolute;_x000D_
 top: -9999px;_x000D_
}
_x000D_
_x000D_
_x000D_

Gives me 17 on my website, 14 here on Stackoverflow.


function getWindowScrollBarHeight() {
    let bodyStyle = window.getComputedStyle(document.body);
    let fullHeight = document.body.scrollHeight;
    let contentsHeight = document.body.getBoundingClientRect().height;
    let marginTop = parseInt(bodyStyle.getPropertyValue('margin-top'), 10);
    let marginBottom = parseInt(bodyStyle.getPropertyValue('margin-bottom'), 10);
    return fullHeight - contentHeight - marginTop - marginBottom;
  }

For me, the most useful way was

(window.innerWidth - document.getElementsByTagName('html')[0].clientWidth)

with vanilla JavaScript.

enter image description here


If you already have an element with scrollbars on it use:

function getScrollbarHeight(el) {
    return el.getBoundingClientRect().height - el.scrollHeight;
};

If there is no horzintscrollbar present the function will retun 0


function getScrollBarWidth() {
    return window.innerWidth - document.documentElement.clientWidth;
}

Most of the browser use 15px for the scrollbar width


With jquery (only tested in firefox):

function getScrollBarHeight() {
    var jTest = $('<div style="display:none;width:50px;overflow: scroll"><div style="width:100px;"><br /><br /></div></div>');
    $('body').append(jTest);
    var h = jTest.innerHeight();
    jTest.css({
        overflow: 'auto',
        width: '200px'
    });
    var h2 = jTest.innerHeight();
    return h - h2;
}

function getScrollBarWidth() {
    var jTest = $('<div style="display:none;height:50px;overflow: scroll"><div style="height:100px;"></div></div>');
    $('body').append(jTest);
    var w = jTest.innerWidth();
    jTest.css({
        overflow: 'auto',
        height: '200px'
    });
    var w2 = jTest.innerWidth();
    return w - w2;
}

But I actually like @Steve's answer better.


You can determine window scroll bar with document as below using jquery + javascript:

var scrollbarWidth = ($(document).width() - window.innerWidth);
console.info("Window Scroll Bar Width=" + scrollbarWidth );

This is a great answer: https://stackoverflow.com/a/986977/5914609

However in my case it did not work. And i spent hours searching for the solution.
Finally i've returned to above code and added !important to each style. And it worked.
I can not add comments below the original answer. So here is the fix:

function getScrollBarWidth () {
  var inner = document.createElement('p');
  inner.style.width = "100% !important";
  inner.style.height = "200px !important";

  var outer = document.createElement('div');
  outer.style.position = "absolute !important";
  outer.style.top = "0px !important";
  outer.style.left = "0px !important";
  outer.style.visibility = "hidden !important";
  outer.style.width = "200px !important";
  outer.style.height = "150px !important";
  outer.style.overflow = "hidden !important";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll !important';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};

if you are looking for a simple operation, just mix plain dom js and jquery,

var swidth=(window.innerWidth-$(window).width());

returns the size of current page scrollbar. (if it is visible or else will return 0)


This life-hack decision will give you opportunity to find browser scrollY width (vanilla JavaScript). Using this example you can get scrollY width on any element including those elements that shouldn't have to have scroll according to your current design conception,:

getComputedScrollYWidth     (el)  {

  let displayCSSValue  ; // CSS value
  let overflowYCSSValue; // CSS value

  // SAVE current original STYLES values
  {
    displayCSSValue   = el.style.display;
    overflowYCSSValue = el.style.overflowY;
  }

  // SET TEMPORALLY styles values
  {
    el.style.display   = 'block';
    el.style.overflowY = 'scroll';
  }

  // SAVE SCROLL WIDTH of the current browser.
  const scrollWidth = el.offsetWidth - el.clientWidth;

  // REPLACE temporally STYLES values by original
  {
    el.style.display   = displayCSSValue;
    el.style.overflowY = overflowYCSSValue;
  }

  return scrollWidth;
}