Javascript scrollIntoView

scrollIntoView scrollt ein Element in den sichtbaren Bereich des Browserfensters, ähnlich wie der Sprung mit <a href="#id"> zum Element mit der ID, aber ohne das Sprungziel als #id in der Navigationsleiste des Browsers zu setzen. scrollTo, scrollBy und scroll scrollen das Browserfenster zu einer Position oder um eine bestimmte Strecke.

Javascript Scrollen: scroll into view

behavior: smooth – weiches Scrollen statt harter Sprung

Ein a-Tag mit einer internen Adresse via id-Attribut ist das älteste und einfachste Verfahren für einen Sprung innerhalb der Seite. Das auslösende HTML-Element braucht eine Sprungadresse und das Zielelement eine passende id.

<a href="#area1">Zu Absatz 4</a>
	…	…	…

<div class="area" id="area1"> … … … </div>

Für den Sprung sorgt HTML allein. Weiches Scrollen – CSS scroll-behavior: smoothanstelle des unvermittelten Sprungs – erlaubt dem Benutzer eine bessere Orientierung und poliert das Verhalten auf.

Javascript behavior: "smooth" ist erst später zu den klassischen Window-Methoden scrollTo, scrollBy und scroll hinzugekommen. Der Sprung funktioniert auch in alten Browsern, nur eben nicht mit weichem Scrollen.

window scrollBy, scrollTo

Die Javascript-Funktionen scrollBy und scrollTo springen zu den angegebenen Koordinaten, denn das vorgegebene Scroll-Verhalten ist scroll-behavior: auto, also kein weiches Scrollen, sondern der direkte Sprung.

Für weiches Scrollen sorgt erst behavior: smooth.

const scrollByBtn = document.querySelector('#scby');
const scrollToBtn = document.querySelector('#scto');

const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const behavior = prefersReducedMotion ? 'auto' : 'smooth';

scrollByBtn?.addEventListener('click', () => {
	window.scrollBy({
		top: 300,
		behavior
	})
});

scrollToBtn?.addEventListener('click', () => {
	window.scrollTo({
		top: 0,
		behavior
	})
});

Optional chaining (?.) führt zu keinem Fehler, wenn das Element nicht existiert (querySelector mit optional chaining).

scroll (x,y)

scrollt zu einer Position x,y des Dokuments: x Pixel auf der horizontalen Achse, y Pixel auf der vertikalen Achse, Nullpunkt ist oben links.

window.scroll (1000,200);

oder

window.scroll({
	top: 1000,
	left: 200,
	behavior: 'smooth'
});

scrollIntoView

Der Sprung mit scrollIntoView fügt der Adresse in der Navigationsleiste des Browsers keine Sprungmarke hinzu und kann ebenfalls durch behavior smooth weich animiert werden.

<li><a href="#area1">Zu Area 1</a></li>
<li><a href="#area2">Zu Area 2</a></li>
<li><a href="#area52">Zu Area 52</a></li>

Mit elem.scrollIntoView() entfällt der Hash-String der URL, der bei einem Sprung mittels HTML-Anker entsteht. Weil auch kein Event feuert, wenn das Scrollziel erreicht ist, kann das Script den Hash zur URL nicht manuell nachführen. Anstelle dessen kann die Browser-History mit history.pushState (null, null, hash) herhalten.

const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches:
const behavior = prefersReducedMotion ? 'auto' : 'smooth':

document.addEventListener('click', (e) => {
	const link = e.target.closest('a[href^="#"]');
	if (!link) return

	const id = link.getAttribute('href').slice(1);
	const target = document.getElementById(id);
	if (!target) return

	e.preventDefault();

	target.scrollIntoView({
		block: 'start',
		behavior
	});

	history.pushState(null, '', `#${id}`);
})

Area 1

Area 2

Area 42?

scroll-margin-top

CSS scroll-margin bewirkt einen Abstand zum angesteuerten Ziel der Scrollaktion. Mit scroll-margin-top schnappt das Target mit einem Abstand zum oberen Rand ein.

.area:nth-of-type(1) { scroll-margin-top: 2rem; }
.area:nth-of-type(2) { scroll-margin-top: 2rem; }
.area:nth-of-type(3) { scroll-margin-top: 2rem; }

Weitere Optionen für scroll-margin:

  • scroll-margin-top, scroll-margin-bottom, scroll-margin-left, scroll-margin-right,
  • scroll-margin-block, scroll-margin-block-end, scroll-margin-block-start.

Unterstützt von allen modernen Browsern.

prefers-reduced-motion

Einigen Besuchern kann von der Animation schwindlig werden. Dagegen kann die CSS Media Query prefers-reduced-motion abgefragt werden.

.smooth-scroll-area {
	scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
	.smooth-scroll-area {
		scroll-behavior: auto;
	}
}

Browser-Unterstützung

scrollIntoView wird von allen Browsern unterstützt (IE seit Version 9); behavior smooth allerdings nicht von IE. Das Polyfill iamdustan/smoothscroll verhilft den Hardlinern ebenfalls zum weichen Scrollen (wenn's denn sein muss).

Abfragen, ob der Browser smooth scroll unterstützt

const smoothScrollSupported = 'scrollBehavior' in document.documentElement.style;

oder mit CSS.supports (neuer, nicht IE11)

//gibt false zurück, wenn scroll-behaviour: smooth nicht unterstützt wird
const smoothScrollSupported = CSS.supports ("behavior","smooth"); // 
Suchen auf mediaevent.de