In another post I wrote on different ways to automatically scroll to an element on a page.

These methods will always trigger page scrolling, but sometimes we’ll want to only do so under certain conditions. For example, if the top of the target element is not visible.

That’s why I created this JavaScript function.

JavaScript function

The following function performs the auto-scroll only if the top of the target element is not visible. This could be because it is outside the viewport, or hidden behind a sticky header.

/**
 * Scrolls to the top of an element if needed.
 *
 * @param {HTMLElement} element The element to scroll to the top of.
 */
function maybeScrollToTopOf(element) {
	const distanceFromTop = element.getBoundingClientRect().top;

	const header = document.querySelector('.sticky-header');
	const headerHeight = header ? header.offsetHeight : 0;

	// If the top of the element is outside the viewport or hidden behind
	// the sticky header, scroll to the top of the element.
	if (
		distanceFromTop <= headerHeight ||
		distanceFromTop >= window.innerHeight
	) {
		element.scrollIntoView();
	}
}

Sticky header height

Note that this function checks the header height. This is because in some cases, the header height may vary between mobile and desktop. So we dynamically check its current height.

It also supports pages that do not contain an header at all (like landing pages). If no sticky header is found, it sets the height to 0.

However, if the height of the sticky header is fixed (no change between mobile and desktop) and is always displayed (on all pages), we can skip the dynamic check and set the fixed height directly in the code.

In the following example, the header height is always 100px:

/**
 * Scrolls to the top of an element if needed.
 *
 * @param {HTMLElement} element The element to scroll to the top of.
 */
function maybeScrollToTopOf(element) {
	const distanceFromTop = element.getBoundingClientRect().top;

	// If the top of the element is outside the viewport or hidden behind
	// the sticky header, scroll to the top of the element.
	if (distanceFromTop <= 100 || distanceFromTop >= window.innerHeight) {
		element.scrollIntoView();
	}
}

Scroll method

Also note that in these examples the actual scrolling is done using the scrollIntoView option, but we could also use other methods described in my other post, such as simulating a click on an anchor link or scrollTo.

For instance, to use the method of simulating a click on an anchor link, we could simply replace the following line:

element.scrollIntoView();

With:

if (element.id) {
	location.href = '#' + element.id;
}

Usage

We can now use this function by passing the target DOM element as a parameter.

For example:

const form = document.querySelector('#signup');

maybeScrollToTopOf(form);