Skip to content

Instantly share code, notes, and snippets.

@zecka
Last active October 27, 2025 10:40
Show Gist options
  • Save zecka/c65971c3d052848fd6fc208beed3a912 to your computer and use it in GitHub Desktop.
Save zecka/c65971c3d052848fd6fc208beed3a912 to your computer and use it in GitHub Desktop.
scrollParentToChild
export const isElementFullyVisible = (element: HTMLElement, topThreshold = 0) => {
if (window && document) {
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
const rect = element.getBoundingClientRect();
return rect.top > topThreshold && rect.bottom < windowHeight;
}
return false;
};
export function scrollParentToChild(parent: Element, child: Element, threshold = 100): void {
// Where is the parent on page
const parentRect = parent.getBoundingClientRect();
// What can you see?
const parentViewableArea = {
height: parent.clientHeight,
width: parent.clientWidth,
};
// Where is the child
const childRect = child.getBoundingClientRect();
// Is the child viewable?
const isViewableVertically =
childRect.top >= parentRect.top &&
childRect.bottom <= parentRect.top + parentViewableArea.height;
const isViewableHorizontally =
childRect.left >= parentRect.left &&
childRect.right <= parentRect.left + parentViewableArea.width;
// if you can't see the child try to scroll parent
if (!isViewableVertically || !isViewableHorizontally) {
// Should we scroll using top or bottom? Find the smaller ABS adjustment
const scrollTop = childRect.top - parentRect.top;
const scrollBot = childRect.bottom - parentRect.bottom;
const scrollLeft = childRect.left - parentRect.left;
const scrollRight = childRect.right - parentRect.right;
if (Math.abs(scrollTop) < Math.abs(scrollBot) && Math.abs(scrollLeft) < Math.abs(scrollRight)) {
// we're nearer to the top and left of the list
parent.scrollTo({
top: parent.scrollTop + scrollTop - threshold,
left: parent.scrollLeft + scrollLeft - threshold,
behavior: 'smooth',
});
} else {
// we're nearer to the bottom and right of the list
parent.scrollTo({
top: parent.scrollTop + scrollBot + threshold,
left: parent.scrollLeft + scrollRight + threshold,
behavior: 'smooth',
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment