Css: How to Get Browser Scrollbar Width? (For :Hover {Overflow: Auto} Nice Margins)

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

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:

  • http://davidwalsh.name/detect-scrollbar-width (original post)
  • http://jsfiddle.net/a1m6an3u/ (live example)

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.

Getting scroll bar width using JavaScript

This function should give you width of scrollbar

function getScrollbarWidth() {

// Creating invisible container
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.overflow = 'scroll'; // forcing scrollbar to appear
outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
document.body.appendChild(outer);

// Creating inner element and placing it in the container
const inner = document.createElement('div');
outer.appendChild(inner);

// Calculating difference between container's full width and the child width
const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth);

// Removing temporary elements from the DOM
outer.parentNode.removeChild(outer);

return scrollbarWidth;

}

Basic steps here are:

  1. Create hidden div (outer) and get it's offset width
  2. Force scroll bars to appear in div (outer) using CSS overflow property
  3. Create new div (inner) and append to outer, set its width to '100%' and get offset width
  4. Calculate scrollbar width based on gathered offsets

Working example here: http://jsfiddle.net/slavafomin/tsrmgcu9/

Update

If you're using this on a Windows (metro) App, make sure you set the -ms-overflow-style property of the 'outer' div to scrollbar, otherwise the width will not be correctly detected. (code updated)

Update #2
This will not work on Mac OS with the default "Only show scrollbars when scrolling" setting (Yosemite and up).

How can I detect the scroll width and differentiate between the mobile and the desktop versions?

I managed to do it by testing the scroll width in the ngOnInit as suggested in this answer (I edited a little for convenience), to test if it was mobile or not:

testIsMobile() {
var scrollbox = document.createElement('div');
scrollbox.style.overflow = 'scroll';
document.body.appendChild(scrollbox);

var scrollWidth = scrollbox.offsetWidth - scrollbox.clientWidth;

document.body.removeChild(scrollbox);

this.isMobile = scrollWidth == 0
}

Then I added the correct class through [ngClass]="fixedHeaderClass"

if (this.isMobile)
this.fixedHeaderClass = "fixed-header-mobile";
else
this.fixedHeaderClass = "fixed-header";

CSS 100% width but avoid scrollbar

Use overflow: scroll instead of overflow: auto - that'll force a scrollbar to always appear.

Make scrollbars only visible when a Div is hovered over?

div {

height: 100px;

width: 50%;

margin: 0 auto;

overflow: hidden;

}

div:hover {

overflow-y: scroll;

}
<div>

<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It

has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop

publishing software like Aldus PageMaker including versions of Lorem Ipsum.

</p>

</div>

Rounded scrollbar that hovers over content

.list {
position: relative;
display: flex;
max-height: 200px;
max-width: 200px;
flex-direction: column;
overflow-y: overlay;
border: 1px solid black;
}

.list::-webkit-scrollbar {
width: 22px;
}

.list::-webkit-scrollbar-track {
width: 20px;
}

.list::-webkit-scrollbar-thumb {
height: 73px;
width: 24px;
background-clip: padding-box;
background-color: rgba(0, 0, 0, 0.25);
border-radius: 15px;
border: 8px solid rgba(0, 0, 0, 0);
}

.list::-webkit-scrollbar-corner {
background-color: transparent;
}

.list::-webkit-scrollbar-corner {
background-color: transparent;
}
<ul class="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7 is pretty long so it goes under</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
<li>item 11</li>
<li>item 12</li>
<li>item 13</li>
<li>item 14</li>
<li>item 15</li>
<li>item 16</li>
<li>item 17</li>
</ul>

How to prevent scrollbar from repositioning web page?

overflow-y:scroll is correct, but you should use it with the html tag, not body or else you get a double scrollbar in IE 7

So the correct css would be:

html {
overflow-y: scroll;
}

Showing scrollbars only when mouseover div

You can make overflow hidden until the mouse is over it, then make it auto.
This is what I did ... note the 16px padding assumes a scrollbar is 16px wide, and is there so the text doesn't re-wrap when the scrollbar appears.

    div.myautoscroll {
height: 40ex;
width: 40em;
overflow: hidden;
border: 1px solid #444;
margin: 3em;
}
div.myautoscroll:hover {
overflow: auto;
}
div.myautoscroll p {
padding-right: 16px;
}
div.myautoscroll:hover p {
padding-right: 0px;
}

See it in action at this fiddle - you'll want to widen the right side "result" window to see the whole box, or reduce the width in the css.


Edit 2014-10-23

There is now more variation in how systems and browsers display scrollbars, so my 16px space may need to be adjusted for your case. The intent of that padding is to prevent the text from being re-flowed as the scrollbar appears and disappears.

Some systems, such as newer versions of Mac OS X (10.8.x at least), don't show scrollbars until you start scrolling which could throw this whole technique off. If the scrollbar doesn't show you may have no reason to hide it until hover, or you may want to leave overflow as auto or even scroll rather than toggling it.



Related Topics



Leave a reply



Submit