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):
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.
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.
$(‘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;
};
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.
Where exactly is the facebook like link ?
My apologies I hadn’t put it on but its just above the comments now.
Chris
does this work in Chrome?
innerHeight doesn’t seem to for me.
btw, one of your ids is wrong too – scrollbardiv ‘2’ not ’12’
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
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
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);
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());
}
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.
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.