jQuery: Calculate Scrollbar Width

I recently needed to calculate the width of the scrollbar for an overflowing div so instead of re-inventing the wheel I went onto Google and did a search. I found a great little post by Jonathan Sharp – Calculating The Browser Scrollbar Width.

Here’s his example (which doesn’t work in Chrome or Safari):


$(function() {
$("#width").text(scrollbarWidth());
});

function scrollbarWidth() {
var div = $('

');
// Append our div, do our calculation and then remove it
$('body').append(div);
var w1 = $('div', div).innerWidth();
div.css('overflow-y', 'scroll');
var w2 = $('div', div).innerWidth();
$(div).remove();
return (w1 – w2);
}

See the Pen bdcBA by Chris Spittles (@chrissp26) on CodePen.
5094

Using the excellent time and timeEnd console commands in FireBug, I outputted the script execution time and worked out an average for 10 passes. The result was 4ms. I know its not very much, but its a lot for a script its size and I started thinking about how to get the execution time down and subsequently how to get it working in Chrome and Safari (thanks to Z for pointing this out).

It would seem as though Webkit browsers have issues with jQuery’s innerWidth (i’m sure someone can correct me here if I’m wrong), but by using the native JavaScript offsetWidth and clientWidth values – which are supported as far as my testing goes – back to IE7 in Internet Explorer browsers and all major browsers since.

By using some of Javascripts native methods (which are faster than jQuery’s most of the time) I’ve got the time down to 1ms which is a 75% faster.

The end result is this:


$(function() {
$("#width").text(scrollbarWidth());
});

function scrollbarWidth() {
var $inner = jQuery('

test
'),
$outer = jQuery('
').append($inner),
inner = $inner[0],
outer = $outer[0];

jQuery('body').append(outer);
var width1 = inner.offsetWidth;
$outer.css('overflow', 'scroll');
var width2 = outer.clientWidth;
$outer.remove();

return (width1 – width2);
}

See the Pen ybaHk by Chris Spittles (@chrissp26) on CodePen.
5094

I’ve tested this in Chrome, Firefox, Opera, IE7, IE8 and IE9 and it works fine.

Many thanks to Jonathan for his excellent script and inspiration and to Z for pointing out the Webkit issues.

9 thoughts on “jQuery: Calculate Scrollbar Width

  1. does this work in Chrome?
    innerHeight doesn’t seem to for me.

    btw, one of your ids is wrong too – scrollbardiv ‘2’ not ’12’

    1. Thanks for pointing out the Chrome issues. I’ve altered the script, but the only way I could get it to work across the board was to revert to some native JS methods. Thanks for the heads up, I have credited your input in the post.

      Chris

  2. Awesome website 😀 I’m so happy I wandered onto it through my friend’s blog going
    to definitely have to add another one to the blogroll

  3. thanks Chris!

    i allowed myself to attach your code to jquery and apply singletone-pattern:

    (function ($, undefined) {
    $.scrollbarWidth = function () {
    var $inner = $(‘test’),
    $outer = $(”).append($inner),
    inner = $inner[0],
    outer = $outer[0];

    $(‘body’).append(outer);
    var width1 = inner.offsetWidth;
    $outer.css(‘overflow’, ‘scroll’);
    var width2 = outer.clientWidth;
    $outer.remove();
    var result = (width1 – width2);

    $.scrollbarWidth = function () {
    return result;
    };

    return result;
    };
    })(jQuery);

  4. Just in case you want a simple function that returns current browser width:

    /**
    * Returns document width with scroll size included.
    * @returns int
    */
    function documentWidth(){

    var $inner = jQuery(‘test’),
    $outer = jQuery(”).append($inner),
    inner = $inner[0],
    outer = $outer[0];

    jQuery(‘body’).append(outer);
    var width1 = inner.offsetWidth;
    $outer.css(‘overflow’, ‘scroll’);
    var width2 = outer.clientWidth;
    $outer.remove();

    var scrollWidth = (width1 – width2);

    if($(document).height() > $(window).height()){
    return parseInt($(document).width()) + parseInt(scrollWidth);
    }
    return parseInt($(document).width());
    }

  5. Thanks. For me this helped a lot especially when a scrollbar can appear / disappear on the same page and you want to reposition dynamically some items.

  6. How about doing this on the same element.

    1) set overflow to ‘hidden’
    2) get w1 = clientWidth
    3) set overflow to ‘scroll’
    4) get w2 = clientWidth
    5) scrollbar width = w2 – w1

    you don’t have to deal with offsetWidth or nested divs.

Leave a Reply

Your email address will not be published. Required fields are marked *