Skip to content

Instantly share code, notes, and snippets.

@oscarmarina
Last active May 7, 2024 19:49
Show Gist options
  • Save oscarmarina/3a546cff4d106a49a5be417e238d9558 to your computer and use it in GitHub Desktop.
Save oscarmarina/3a546cff4d106a49a5be417e238d9558 to your computer and use it in GitHub Desktop.
Returns the scroll parent of an element along a specified axis and the scroll size and client size.
/**
* Returns the scroll parent of an element along a specified axis and the scroll size and client size.
*
* @param {HTMLElement} el - The element to find the scroll parent of.
* @param {String} [axis='y'] - The axis to find the scroll parent for.
* @returns {Object} An object with the following properties:
* @property {HTMLElement} scrollParent - The scroll parent element.
* @property {Number} scrollParentSize - The size of the scroll parent along the specified axis.
* @property {Number} clientParentSize - The size of the scroll parent's client area along the specified axis.
*/
export const getScrollParent = (node, axis = 'y') => {
let el = node;
if (!(el instanceof HTMLElement || el instanceof ShadowRoot)) {
return null;
}
if (el instanceof ShadowRoot) {
el = el.host;
}
const style = window.getComputedStyle(el);
const overflow = axis === 'y' ? style.overflowY : style.overflowX;
const scrollSize = axis === 'y' ? el.scrollHeight : el.scrollWidth;
const clientSize = axis === 'y' ? el.clientHeight : el.clientWidth;
const isScrolled = scrollSize > clientSize;
if (isScrolled && !overflow.includes('visible') && !overflow.includes('hidden')) {
return {
scrollParent: el,
scrollParentSize: scrollSize,
clientParentSize: clientSize,
};
}
return getScrollParent(el.parentNode, axis) || document.body;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment