Detect if a page has a vertical scrollbar?

JavascriptJqueryScroll

Javascript Problem Overview


I just want some simple JQ/JS to check if the current page/window (not a particular element) has a vertical scrollbar.

Googling gives me stuff that seems overly complex for just this basic feature.

How can this be done?

Javascript Solutions


Solution 1 - Javascript

$(document).ready(function() {
	// Check if body height is higher than window height :)
	if ($("body").height() > $(window).height()) {
		alert("Vertical Scrollbar! D:");
	}

	// Check if body width is higher than window width :)
	if ($("body").width() > $(window).width()) {
		alert("Horizontal Scrollbar! D:<");
	}
});

Solution 2 - Javascript

try this:

var hasVScroll = document.body.scrollHeight > document.body.clientHeight;

This will only tell you if the vertical scrollHeight is bigger than the height of the viewable content, however. The hasVScroll variable will contain true or false.

If you need to do a more thorough check, add the following to the code above:

// Get the computed style of the body element
var cStyle = document.body.currentStyle||window.getComputedStyle(document.body, "");

// Check the overflow and overflowY properties for "auto" and "visible" values
hasVScroll = cStyle.overflow == "visible" 
             || cStyle.overflowY == "visible"
             || (hasVScroll && cStyle.overflow == "auto")
             || (hasVScroll && cStyle.overflowY == "auto");

Solution 3 - Javascript

I tried the previous answer and doesn't seem to be working the $("body").height() does not necessarily represent the whole html height.

I have corrected the solution as follows:

// Check if body height is higher than window height :) 
if ($(document).height() > $(window).height()) { 
    alert("Vertical Scrollbar! D:"); 
} 
 
// Check if body width is higher than window width :) 
if ($(document).width() > $(window).width()) { 
    alert("Horizontal Scrollbar! D:<"); 
} 

Solution 4 - Javascript

Let's bring this question back from the dead ;) There is a reason Google doesn't give you a simple solution. Special cases and browser quirks affect the calculation, and it is not as trivial as it seems to be.

Unfortunately, there are problems with the solutions outlined here so far. I don't mean to disparage them at all - they are great starting points and touch on all the key properties needed for a more robust approach. But I wouldn't recommend copying and pasting the code from any of the other answers because

  • they don't capture the effect of positioned content in a way that is reliable cross-browser. The answers which are based on body size miss this entirely (the body is not the offset parent of such content unless it is positioned itself). And those answers checking $( document ).width() and .height() fall prey to jQuery's buggy detection of document size.
  • Relying on window.innerWidth, if the browser supports it, makes your code fail to detect scroll bars in mobile browsers, where the width of the scroll bar is generally 0. They are just shown temporarily as an overlay and don't take up space in the document. Zooming on mobile also becomes a problem that way (long story).
  • The detection can be thrown off when people explicitly set the overflow of both the html and body element to non-default values (what happens then is a little involved - see this description).
  • In most answers, body padding, borders or margins are not detected and distort the results.

I have spent more time than I would have imagined on a finding a solution that "just works" (cough). The algorithm I have come up with is now part of a plugin, jQuery.isInView, which exposes a .hasScrollbar method. Have a look at the source if you wish.

In a scenario where you are in full control of the page and don't have to deal with unknown CSS, using a plugin may be overkill - after all, you know which edge cases apply, and which don't. However, if you need reliable results in an unknown environment, then I don't think the solutions outlined here will be enough. You are better off using a well-tested plugin - mine or anybody elses.

Solution 5 - Javascript

This one did works for me:

function hasVerticalScroll(node){
	if(node == undefined){
		if(window.innerHeight){
			return document.body.offsetHeight> window.innerHeight;
		}
		else {
			return  document.documentElement.scrollHeight > 
				document.documentElement.offsetHeight ||
				document.body.scrollHeight>document.body.offsetHeight;
		}
	}
	else {
		return node.scrollHeight> node.offsetHeight;
	}
}

For the body, just use hasVerticalScroll().

Solution 6 - Javascript

let hasScrollbar = window.innerWidth > document.documentElement.clientWidth;

Solution 7 - Javascript

Oddly none of these solutions tell you if a page has a vertical scrollbar.

window.innerWidth - document.body.clientWidth will give you the width of the scrollbar. This should work in anything IE9+ (not tested in the lesser browsers). (Or to strictly answer the question, !!(window.innerWidth - document.body.clientWidth)

Why? Let's say you have a page where the content is taller than the window height and the user can scroll up/down. If you're using Chrome on a Mac with no mouse plugged in, the user will not see a scrollbar. Plug a mouse in and a scrollbar will appear. (Note this behaviour can be overridden, but that's the default AFAIK).

Solution 8 - Javascript

    <script>
    var scrollHeight = document.body.scrollHeight;
    var clientHeight = document.documentElement.clientHeight;
    var hasVerticalScrollbar = scrollHeight > clientHeight;

    alert(scrollHeight + " and " + clientHeight); //for checking / debugging.
    alert("hasVerticalScrollbar is " + hasVerticalScrollbar + "."); //for checking / debugging.
    </script>

This one will tell you if you have a scrollbar or not. I've included some information that may help with debugging, which will display as a JavaScript alert.

Put this in a script tag, after the closing body tag.

Solution 9 - Javascript

I found vanila solution

var hasScrollbar = function() {
  // The Modern solution
  if (typeof window.innerWidth === 'number')
    return window.innerWidth > document.documentElement.clientWidth

  // rootElem for quirksmode
  var rootElem = document.documentElement || document.body

  // Check overflow style property on body for fauxscrollbars
  var overflowStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowStyle = rootElem.currentStyle.overflow

  overflowStyle = overflowStyle || window.getComputedStyle(rootElem, '').overflow

    // Also need to check the Y axis overflow
  var overflowYStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowYStyle = rootElem.currentStyle.overflowY

  overflowYStyle = overflowYStyle || window.getComputedStyle(rootElem, '').overflowY

  var contentOverflows = rootElem.scrollHeight > rootElem.clientHeight
  var overflowShown    = /^(visible|auto)$/.test(overflowStyle) || /^(visible|auto)$/.test(overflowYStyle)
  var alwaysShowScroll = overflowStyle === 'scroll' || overflowYStyle === 'scroll'

  return (contentOverflows && overflowShown) || (alwaysShowScroll)
}

Solution 10 - Javascript

I use

function windowHasScroll()
{
    return document.body.clientHeight > document.documentElement.clientHeight;
}

Solution 11 - Javascript

Simply compare the width of the documents root element (i.e. html element) against the inner portion of the window:

if ((window.innerWidth - document.documentElement.clientWidth) >0) console.log('V-scrollbar active')

If you also need to know the scrollbar width:

vScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;

Solution 12 - Javascript

Other solutions didn't work in one of my projects and I've ending up checking overflow css property

function haveScrollbar() {
    var style = window.getComputedStyle(document.body);
    return style["overflow-y"] != "hidden";
}

but it will only work if scrollbar appear disappear by changing the prop it will not work if the content is equal or smaller than the window.

Solution 13 - Javascript

I wrote an updated version of Kees C. Bakker's answer:

const hasVerticalScroll = (node) => {
  if (!node) {
    if (window.innerHeight) {
      return document.body.offsetHeight > window.innerHeight
    }
    return (document.documentElement.scrollHeight > document.documentElement.offsetHeight)
      || (document.body.scrollHeight > document.body.offsetHeight)
  }
  return node.scrollHeight > node.offsetHeight
}

if (hasVerticalScroll(document.querySelector('body'))) {
  this.props.handleDisableDownScrollerButton()
}

The function returns true or false depending whether the page has a vertical scrollbar or not.

For example:

const hasVScroll = hasVerticalScroll(document.querySelector('body'))

if (hasVScroll) {
  console.log('HAS SCROLL', hasVScroll)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWoodyView Question on Stackoverflow
Solution 1 - JavascriptThiago BelemView Answer on Stackoverflow
Solution 2 - JavascriptAndy EView Answer on Stackoverflow
Solution 3 - JavascriptBharatView Answer on Stackoverflow
Solution 4 - JavascripthashchangeView Answer on Stackoverflow
Solution 5 - JavascriptKees C. BakkerView Answer on Stackoverflow
Solution 6 - JavascriptRoman ZaykovskyView Answer on Stackoverflow
Solution 7 - JavascriptDavid GilbertsonView Answer on Stackoverflow
Solution 8 - JavascriptDon D.View Answer on Stackoverflow
Solution 9 - JavascriptSergii ShvagerView Answer on Stackoverflow
Solution 10 - JavascriptamossView Answer on Stackoverflow
Solution 11 - JavascriptBabakView Answer on Stackoverflow
Solution 12 - JavascriptjcubicView Answer on Stackoverflow
Solution 13 - Javascriptagm1984View Answer on Stackoverflow