Getting scroll bar width using JavaScript [duplicate] - javascript

This question already has answers here:
How can I get the browser's scrollbar sizes?
(25 answers)
Closed 5 years ago.
The following HTML will display a scroll bar on the right inside edge of div.container.
Is it possible to determine the width of that scroll bar?
<div class="container" style="overflow-y:auto; height:40px;">
<div class="somethingBig"></div>
</div>

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:
Create hidden div (outer) and get it's offset width
Force scroll bars to appear in div (outer) using CSS overflow property
Create new div (inner) and append to outer, set its width to '100%' and get offset width
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).

offsetWidth includes width of scroll bar and clientWidth doesn't. As rule, it equals 14-18px. So:
let scrollBarWidth = element.offsetWidth - element.clientWidth;
That will return 0 if the element doesn't currently have a scroll bar, so here's a simple function which computes the browser's scroll bar width by creating a temporary element that has a scroll bar:
function getScrollBarWidth() {
let el = document.createElement("div");
el.style.cssText = "overflow:scroll; visibility:hidden; position:absolute;";
document.body.appendChild(el);
let width = el.offsetWidth - el.clientWidth;
el.remove();
return width;
}

I think this will be simple and fast -
var scrollWidth= window.innerWidth-$(document).width()

If the child takes the full width of the container excluding scrollbar (the default), then you can subtract the widths:
var child = document.querySelector(".somethingBig");
var scrollbarWidth = child.parentNode.offsetWidth - child.offsetWidth;

If you use jquery.ui, try this code:
$.position.scrollbarWidth()

I've used next function to get scrollbar height/width:
function getBrowserScrollSize(){
var css = {
"border": "none",
"height": "200px",
"margin": "0",
"padding": "0",
"width": "200px"
};
var inner = $("<div>").css($.extend({}, css));
var outer = $("<div>").css($.extend({
"left": "-1000px",
"overflow": "scroll",
"position": "absolute",
"top": "-1000px"
}, css)).append(inner).appendTo("body")
.scrollLeft(1000)
.scrollTop(1000);
var scrollSize = {
"height": (outer.offset().top - inner.offset().top) || 0,
"width": (outer.offset().left - inner.offset().left) || 0
};
outer.remove();
return scrollSize;
}
This jQuery-based solutions works in IE7+ and all other modern browsers (including mobile devices where scrollbar height/width will be 0).

Here's an easy way using jQuery.
var scrollbarWidth = jQuery('div.withScrollBar').get(0).scrollWidth - jQuery('div.withScrollBar').width();
Basically we subtract the scrollable width from the overall width and that should provide the scrollbar's width. Of course, you'd want to cache the jQuery('div.withScrollBar') selection so you're not doing that part twice.

Assuming container is only on page once and you are using jQuery, then:
var containerEl = $('.container')[0];
var scrollbarWidth = containerEl.offsetWidth - containerEl.clientWidth;
Also see this answer for more details.

this worked for me..
function getScrollbarWidth() {
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
$('body').append(div);
var w1 = $('div', div).innerWidth();
div.css('overflow-y', 'scroll');
var w2 = $('div', div).innerWidth();
$(div).remove();
return (w1 - w2);
}

Related

JavaScript: How to get a dynamically created element's width?

I'm a JavaScript novice. Have patience with me.
I searched this site for relevant questions and found two: How to get width of a dynamically created element with $comiple in Angularj and jQuery + CSS. How do I compute height and width of innerHTML?. Their relevance and their answers are discussed below. If I missed a relevant question and this is a duplicate question, please direct me to it.
I dynamically create a <div class="popup"> (call it "popup"), populate it with innerHTML from a display: none; <div> in the markup, and insert it on the page. The relevant CSS is:
.popup {
top: 0;
left: 0;
width: 200px;
height: 250px;
}
Using event.clientX, I position popup relative to the cursor position at the time the mouseover event fired, as follows:
var widthOffset = 75, heightOffset = 0;
var windowWidth, popupWidth;
// other code ...
windowWidth = $(window).width();
popupWidth = 200; // popup.style.width returns nothing (not null,
// not undefined, just nothing).
// when event.clientX is in the left half of the window, display popup
// offset to the right of clientX;
// when clientX is in the right half, display popup offset to the left.
if( event.clientX > windowWidth/2 ){ widthOffset = -(widthOffset + popupWidth);}
popup.style.top = event.clientY - heightOffset + "px";
popup.style.left = event.clientX + widthOffset + "px";
There is a working reduced case at the Pen Popup Project Reduced Case on CodePen.
The problem is that I want to programmatically obtain popupWidth not set it as a fixed quantity. But, as the comment states,
popupWidth = popup.style.width;
is nothing. (Maybe it's a null string: popupWidth === "". I'm uncertain.)
The answer to the first question referenced above said to insert popup into the DOM before trying to obtain its width. I have done this. (See the Pen.) Still, it doesn't work.
A comment to the second answer to the second question said:
the root issues is that height cannot be set on an element with display:none.
I had display: none but when I changed it to display: block, and set popupWidth = popup.style.width;, popup "stuttered" fiercely on mouseover.
So the question remains: How do I programmatically get popupWidth just as I did with windowWidth?
With help from #Redu and #torazaburo, the answer became clear.
popupWidth = popup.offsetWidth; is the correct statement but both these conditions must be true:
popup must have been inserted into the DOM, and
display: block; must have been set.
If popup is still in memory or display: block; has not been set, then popup.offsetWidth === 0. If both of the conditions are true, then popup.offsetWidth is equal to the width set in the CSS.
Thanks to both commenters for their help.
You can do like
var popupDiv = document.getElementsByClassName("popup")[0],
width = window.getComputedStyle(popupDiv).width;
If you deal with a window or document type of element then getElementsByClassName(element,null), element.offsetWidth or element.clientWidth doesn't work. You have to access the width value like
var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

Positioning div off-screen to the right using jQuery

Strictly using JavaScript, I'd like to position the following div element right outside the window, to the right, so that no horizontal scrollbar is present.
How do I do this?
HTML:
<div id = "content">
<header>
<h2>Welcome!</h2>
</header>
</div>
I was thinking something like
$( "#content" ).offset({ left: 1345});
but that unfortunately results in a scrollbar, and it isn't responsive, causing the div to be located far outside the right edge of the window when in mobile view.
If you take the window.innerWidth; value and set that as the left position value it'll hang out right outside of the viewports width.
You'd need to set either your wrapper or body to overflow: hidden; to get rid of the horizontal scroll though.
var hiddenDiv = document.getElementById('content');
var docWidth = window.innerWidth;
hiddenDiv.style.position = 'relative'; // Or absolute, depending on what you want
hiddenDiv.style.display = 'inline-block';
hiddenDiv.style.left = docWidth+'px';
http://jsfiddle.net/c62sqvdk/ <-- JsFiddle for visual example.
Why not just hide it? You can easily do it with javascript with
var link = document.getElementById('content');
link.style.display = 'none';
link.style.visibility = 'hidden';
Depends on what you need it for.
Also, check this https://daneden.github.io/animate.css/
Try
document.body.style.overflow = "hidden";
var content = document.getElementById("content");
content.style.position = "absolute";
content.style.left = window.innerWidth + "px";
jquery
$(function() {
$("body").css("overflow", "hidden")
.find("#content").css({
"position" : "absolute",
"left" : window.innerWidth
});
});
jsfiddle http://jsfiddle.net/guest271314/9zhy2xax/

need 100% div without setting a fixed height on container div

Here is a link to a JSFiddle http://jsfiddle.net/9NYcn/11/ i put together with what i would like to do, but i need to do this with pure css.
function expand(){
var sect = document.getElementById("sect");
var body = document.getElementById("main");
var panes = document.getElementById("panes");
var newHeight = 40 + "px";
var newHeight2 = 120 + "px";
var topVal = 120 + "px";
sect.style.display = "block";
sect.style.height = newHeight;
body.style.height = newHeight2;
panes.style.top = topVal;
}
In the above function i had to set the "top" property of panes in order to get this to work. i need to get it so that the panes section will work like it currently does without using javascript to change the "top" property of "panes". When the user clicks the "expand" button the div with the class "body" will expand and not stick behind or overlap the "panes" div.
I know im doing a terrible job explaining i apologize for that.
Remove the absolute positioning of .panes: http://jsfiddle.net/rHTM8/
It will make it naturally flow after the middle div.

Determine whether mouse is always on the bottom of the page

How can I determine whether mouse is always on the bottom of the viewport? Let us assume that by bottom we mean the bottom 100 pixels of a given page (on a long scrolling page).
this is an example, check the arrow
http://discover.store.sony.com/tablet/#design/weight-distribution
Easy!
Calculate how much of that "bottom" area is showing in the current window with window.screen.height and document.height.
Then use onmousemove event to calculate if the mouse is stepping over that area.
Create a blank div with the dimensions that you want, use CSS to position:absolute; it on the bottom and z-index it above the other elements, then create a onHover to detect if the mouse is there
EDIT
This might work as a solution to avoid using CSS method above (untested)
$(function(){
$.mousemove(function(e){
var wHeight = $(window).height();
var yMouse = e.pageY;
if(yMouse > (wHeight - 100)) {
// Do something
}
});
});
I think i solved myself based on Pastor Bones code:
you have to calculate the window scrolltop
var scrollT = $(window).scrollTop() + wHeight;
so:
$(function(){
$.mousemove(function(e){
var wHeight = $(window).height();
var scrollT = $(window).scrollTop() + wHeight;
var yMouse = e.pageY;
if(yMouse > (scrollT - 100)) {
// Do something
}
});
});

How to find actual rendered values of elements set to 'auto' using JavaScript

Suppose I have the following html, and no CSS
<div>
here is some content in this div. it stretches it out
<br />and down too!
</div>
Now I want to get the actual pixel width and height that the browser has rendered this div as.
Can that be done with JS?
Thank you.
Try getting a reference to your div and reading the offsetWidth and offsetHeight properties:
var myDiv = document.getElementById('myDiv');
var width = myDiv.offsetWidth; // int
var height = myDiv.offsetHeight;
offsetWidth/Height cumulatively measures the element's borders, horizontal padding, vertical scrollbar (if present, if rendered) and CSS width. It's the pixel values of the entire space that the element uses in the document. I think it's what you want.
If that is not what you meant, and you'd rather only the element's width and height (i.e. excluding padding, margin, etc) try getComputedStyle:
var comStyle = window.getComputedStyle(myDiv, null);
var width = parseInt(comStyle.getPropertyValue("width"), 10);
var height = parseInt(comStyle.getPropertyValue("height"), 10);
The values above will be the final, computed pixel values for the width and height css style properties (including values set by a <style> element or an external stylesheet).
Like all helpful things, this won't work in IE.
You say you are using jQuery. Well it's trivial now, and works cross-browser:
var width = $('div').css('width');
var height = $('div').css('height');
With jQuery you don't need the first part of this answer, it's all taken care of for ya ;)
One of the benefits of using a framework, like Prototype, is that the framework authors have usually sorted out the portability issues. Even if you don't use the framework, it can still be instructive to read. In the case of Prototype, the code for reading the dimensions of an element accounts for a Safari issue and allows you to read the width of an element that is not presently dislayed.
getDimensions: function(element) {
element = $(element);
var display = $(element).getStyle('display');
if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
// All *Width and *Height properties give 0 on elements with display none,
// so enable the element temporarily
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
},
For the jQuery framework, .height and .width do the job.

Categories

Resources