Skip to content

Instantly share code, notes, and snippets.

@dperini
Last active September 5, 2020 22:53
Show Gist options
  • Save dperini/ac3d921d6a08f10fd10e to your computer and use it in GitHub Desktop.
Save dperini/ac3d921d6a08f10fd10e to your computer and use it in GitHub Desktop.
/*
* How to detect which element is the scrolling element in charge of scrolling the viewport:
*
* - in Quirks mode the scrolling element is the "body"
* - in Standard mode the scrolling element is the "documentElement"
*
* webkit based browsers always use the "body" element, disrespectful of the specifications:
*
* http://dev.w3.org/csswg/cssom-view/#dom-element-scrolltop
*
* This feature detection helper allow cross-browser scroll operations on the viewport,
* it will guess which element to use in each browser both in Quirk and Standard modes.
* See how this can be used in a "smooth scroll to anchors references" example here:
*
* https://dl.dropboxusercontent.com/u/598365/scrollTo/scrollTo.html
*
* It is just a fix for possible differences between browsers versions (currently any Webkit).
* In case the Webkit bug get fixed someday, it will just work if they follow the specs. Win !
*
* Author: Diego Perini
* Updated: 2014/09/18
* License: MIT
*
*/
function getScrollingElement() {
var d = document;
return d.documentElement.scrollHeight > d.body.scrollHeight &&
d.compatMode.indexOf('CSS1') == 0 ?
d.documentElement :
d.body;
}
@mathiasbynens
Copy link

This code is now being used (with Diego’s permission) in a document.scrollingElement polyfill: https://github.com/mathiasbynens/document.scrollingElement

@RByers
Copy link

RByers commented Apr 24, 2015

Actually, I don't understand this logic at all. In most cases in Chrome and Firefox, document.body.scrollHeight == document.documentElement.scrollHeight and so you'll get 'body' even when that's not correct. Other than wacky cases where both html and body have 'overflow' set, I believe these values always both include the document scroll height. They can be different when the body has additional margin/padding but that still doesn't give you any signal about which element is the scroller and so shouldn't be impacting the return value.

Is there a case I'm missing? Can you give me an example where this actually returns 'documentElement'?

@RByers
Copy link

RByers commented Apr 24, 2015

Oh, I think I see. This relies on body having some margin. In that case I think it does work. I was testing on a few pages that happened to have 'body {margin: 0};' (not an uncommon pattern) where it falls down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment