CSS: How to get browser scrollbar width? (for :hover {overflow: auto} nice margins)

Jacek Kowalewski picture Jacek Kowalewski · Feb 6, 2015 · Viewed 51.8k times · Source

I'm not sure if title is clear, so few words of explanation. I've got few little elements, let say div's (200px x 400px CONSTANT). Inside each of them, there is a paragraph with about 20 lines of text. Of course, this it to much for a poor little div. What I want to do is:

  1. Normally div has overflow: hidden property.
  2. On mouse over (:hover) this property is changed to overflow: auto;, and the scrollbar appears.

What is the problem? I want a little space (padding or margin) between the paragraph text and the scrollbar. Let's say that paragraph has a symetrical margin: 20px;. But after :hover triggers on, the scrollbar appears, and the whole right side of the paragraph is moved "scrollbar-width" px to the left. Sentences are broken in other lines, and the whole paragraph look different, which is quite annoying and not user friendly. How can I set my CSS, so the only change after hover will be the appearance of scroolbar?

In other words:

/* Normally no scrollbar */
div {display: block; width: 400px; height: 200px; overflow: hidden;}
/* On hover scrollbar appears */
div:hover {overflow: auto;}

/* Paragraph margin predicted for future scrollbar on div */
div p {margin: 20px (20px + scrollbarwidth px) 20px 50px;}
/* With scrollbar margin is symmetrical */
div:hover p {margin: 20px;} /* With scrollbar */

I have done a little snippet for it, with exaplanation of my problem in strong. I hope everything is clear :). I'm searching for a solution for almost two hours now, so I think my question is quite unique and interesting.

Answer

tomtomtom picture tomtomtom · Feb 6, 2015

Scrollbar widths can vary between browsers and operating systems, and unfortunately CSS does not provide a way to detect those widths: we need to use JavaScript.

Other people have solved this problem by measuring the width of the scrollbar on an element:

We create a div .scrollbar-measure, add a scrollbar, and return its size.

// Create the div
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.warn(scrollbarWidth);

// Delete the div
document.body.removeChild(scrollDiv);

This is fairly straightforward, but it is (obviously) not pure CSS.