Getting the scrollbar width in pixels

Getting the scrollbar width in pixels

over 2 years ago / 3 Comments

Update: The code in this post is licensed under the terms of the Apache License, version 2.

Working on the new fluid layout code for Scooby, I had a seemingly intractable problem -- I needed to do percent-based side-to-side alignment of elements inside two div elements, one positioned directly above the other. The catch was that the lower div scrolled, and the upper one did not.

I tried two or three different things, but couldn't get around it -- ultimately I needed to set a horizontal offset on the top div that would be the same precise width as the scrollbar in the div below.

Interestingly, the irritatating IE bug of calculating the 100% width before adding scrollbars to a scrolling div makes this unnecessary -- all you have to do is set the same arbitrary offset for both div elements (as long as it's wider than any Windows scrollbar might be so you don't end up with content under the scroller).

For the well-behaved browsers, though, I just decided to do some hacking, and came up with something that reliably gives you the actual pixel width of the scroller. There is likely a better way to do it, but here's what I ended up with:

function getScrollerWidth() {
var scr = null;
var inn = null;
var wNoScroll = 0;
var wScroll = 0;
// Outer scrolling div
scr = document.createElement('div');
scr.style.position = 'absolute';
scr.style.top = '-1000px';
scr.style.left = '-1000px';
scr.style.width = '100px';
scr.style.height = '50px';
// Start with no scrollbar
scr.style.overflow = 'hidden';
// Inner content div
inn = document.createElement('div');
inn.style.width = '100%';
inn.style.height = '200px';
// Put the inner div in the scrolling div
scr.appendChild(inn);
// Append the scrolling div to the doc
document.body.appendChild(scr);
// Width of the inner div sans scrollbar
wNoScroll = inn.offsetWidth;
// Add the scrollbar
scr.style.overflow = 'auto';
// Width of the inner div width scrollbar
wScroll = inn.offsetWidth;
// Remove the scrolling div from the doc
document.body.removeChild(
document.body.lastChild);
// Pixel width of the scroller
return (wNoScroll - wScroll);
}

Okay, so it's fairly obvious and a bit brute-force.

All it does is add a couple of div elements to the document and actually measure widths with and without the scroller. But I was pretty excited to be able to grab that value correctly and reliably for Safari, as well as for Firefox on Linux and on Windows -- with both the XP "Hasbro" look and the old-skool Soviet-bloc style.

And of course, as you might guess, it's different everywhere. Yes, it is.

Comments

Scott   over 2 years ago
Thanks so much for providing the script. I was having exactly the same problem as you were: two div elements, one above the other, and the lower one scrolled. After a bit of searching, I came across this and my problem was solved. Thanks again! Scott
mde   over 2 years ago
Cool. I'm really glad this was able to help someone else out. It make me mind those browser differences a bit less when I can get an accurate picture of what they are.
Cathy   over 2 years ago
Thanks for sharing this script Matthew. It's solved a problem I was having with a liquid layout containing a pixel sized flash movie. I had to calculate the size of the flash parent element and use that value to work out how wide the flash movie should be displayed. In firefox using clientWidth was making the flash too wide - I just needed to minus the width of the scrollbar.
posted @ 2008-07-10 16:04  南守拥  阅读(454)  评论(0编辑  收藏  举报