How to calculate the width of the scroll bar?

34,571

Solution 1

There is a jQuery plugin that can help with this: https://github.com/brandonaaron/jquery-getscrollbarwidth/blob/master/jquery.getscrollbarwidth.js

Also, from http://www.alexandre-gomes.com/?p=115 Here is some code that may help.

This creates a hidden <p> element at 100% width inside a <div> with a scrollbar, then calculates the <div> width - the <p> width = scroll bar width.

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

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

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

  document.body.removeChild (outer); 

  return (w1 - w2); 
}; 

Solution 2

Scrollbar width is simply (offsetWidth - clientWidth) in a borderless! element. This function calculates it on the fly and caches the result for further use. No need need for percentage width etc.

var getScrollbarWidth = function() {
  var div, width = getScrollbarWidth.width;
  if (width === undefined) {
    div = document.createElement('div');
    div.innerHTML = '<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>';
    div = div.firstChild;
    document.body.appendChild(div);
    width = getScrollbarWidth.width = div.offsetWidth - div.clientWidth;
    document.body.removeChild(div);
  }
  return width;
};

Solution 3

Maybe you could put

overflow-y:scroll;

in your css. This forces the scrollbar to be present even when the text area is blank, so the width is always constant.

Solution 4

I believe this is a more straightforward solution: (assuming body {width:100%;})

function calculateScrollBarWidth() {
  return window.innerWidth - document.body.clientWidth;
}

A solution to calculate the scrollbar width of any element (e.g. a div with overflow, or a textarea)

function calculateScrollbarWidth(element) {
  if (!element) {
    // Return the body scrollbar width, when no element was specified.
    return window.innerWidth - document.body.clientWidth;
  } else {
    // When an element is specified, return its specific scrollbar width.
    return element.offsetWidth - element.clientWidth;
  }
}

Solution 5

Using jQuery, simply write:

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;
};
Share:
34,571
Misha Moroshko
Author by

Misha Moroshko

I build products that make humans happier. Previously Front End engineer at Facebook. Now, reimagining live experiences at https://muso.live

Updated on July 09, 2022

Comments

  • Misha Moroshko
    Misha Moroshko almost 2 years

    Given a <textarea> with a fixed width, I would like its "active width" to be constant (in px). By "active width" I mean the area where the text appears.

    When the vertical scroll bar doesn't appear, the "active width" equals to width. But, when the vertical scroll bar appears, the "active width" becomes smaller than width (I guess smaller exactly by the width of the scroll bar).

    I thought to identify whether the vertical scroll bar appears or not, and if yes, to increase the width of the <textarea> by the width of the scroll bar. How could I identify the width of the scroll bar?

    Is there a better approach?

    (I'm interested in Firefox, if it makes the life easier.)

  • Misha Moroshko
    Misha Moroshko over 12 years
    Did you test this? When the scroll bar doesn't appear, it still returns a non-zero value.
  • Dustin Poissant
    Dustin Poissant over 7 years
    I get the error "cannot ready property 'appendChild' of null"
  • Dustin Poissant
    Dustin Poissant over 7 years
    Returns "NaN" - Chrome 54
  • Joshua Bambrick
    Joshua Bambrick over 7 years
    Are you sure? It appears to return 0 for me because Chrome's new scrollbars take up no space
  • kofifus
    kofifus over 6 years
    the Google Closure Library solution works best, thx! the slickgrid solution is broken see github.com/6pac/SlickGrid/pull/149
  • goldylucks
    goldylucks almost 5 years
    This should be accpeted answer
  • Philipp
    Philipp over 3 years
    Perfect solution! Here's another sample on how to calculate the scrollbar width of any element (not only the body): javascripttutorial.net/dom/css/…
  • tonitone120
    tonitone120 about 3 years
    For me, using Chrome version 89, window.innerWidth & document.documentElement.clientWidth return the same value