Signatur
Beschreibung
Element.scrollBy() verschiebt die Scrollposition eines scrollbaren Elements relativ zur aktuellen Position. Anders als bei scrollTo() gibt man keine Zielkoordinaten an, sondern eine Differenz: scrollBy(0, 100) scrollt 100 Pixel nach unten, egal wo das Element gerade steht. Negative Werte scrollen nach oben bzw. links.
Die Methode kann auf zwei Arten aufgerufen werden: mit zwei Zahlen (x, y) oder mit einem Optionsobjekt { top, left, behavior }. Nur mit dem Optionsobjekt lässt sich per behavior: "smooth" ein weiches, animiertes Scrollen anfordern.
Typische Einsatzfälle sind Karussells und Slider mit „Weiter“-/„Zurück“-Buttons, Tastatursteuerung in eigenen Listen, schrittweises Nachscrollen in Chat-Verläufen oder das Blättern um genau eine Containerhöhe (Seitenweise-Scrollen).
Damit die Methode etwas bewirkt, muss das Element tatsächlich scrollbar sein, also overflow: auto oder overflow: scroll besitzen und einen Inhalt haben, der größer als der sichtbare Bereich ist. Werte außerhalb des möglichen Bereichs werden automatisch auf die Grenzen begrenzt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $x | number | Horizontaler Scrollbetrag in Pixeln (Variante mit zwei Zahlen). Positiv = nach rechts, negativ = nach links. | |
| $y | number | Vertikaler Scrollbetrag in Pixeln (Variante mit zwei Zahlen). Positiv = nach unten, negativ = nach oben. | |
| $options | ScrollToOptions | {} | Alternativ ein Objekt mit folgenden Feldern:
|
Rückgabewert
undefined). Die Methode liefert auch kein Promise – das Ende einer weichen Scroll-Animation lässt sich über das Event scrollend erkennen.Beispiele
Einfach: Container um 200 Pixel nach unten scrollen
const list = document.querySelector('#nachrichten');
// Sofort um 200 px nach unten scrollen
list.scrollBy(0, 200);
console.log(list.scrollTop);
Karussell mit Weiter-/Zurück-Buttons und weichem Scrollen
const track = document.querySelector('.karussell');
const prev = document.querySelector('.karussell-zurueck');
const next = document.querySelector('.karussell-weiter');
// Um genau eine sichtbare Breite blättern
const blaettern = (richtung) => {
track.scrollBy({
left: richtung * track.clientWidth,
behavior: 'smooth'
});
};
prev.addEventListener('click', () => blaettern(-1));
next.addEventListener('click', () => blaettern(1));
Tastatursteuerung: Seitenweise scrollen in einer eigenen Liste
const panel = document.querySelector('#log-ausgabe');
panel.tabIndex = 0; // fokussierbar machen
panel.addEventListener('keydown', (event) => {
const seite = panel.clientHeight * 0.9;
if (event.key === 'j') {
panel.scrollBy({ top: 40, behavior: 'smooth' });
} else if (event.key === 'k') {
panel.scrollBy({ top: -40, behavior: 'smooth' });
} else if (event.key === ' ') {
event.preventDefault();
panel.scrollBy({ top: event.shiftKey ? -seite : seite, behavior: 'smooth' });
}
});
Ende der weichen Scroll-Animation abwarten
const box = document.querySelector('.scroll-box');
const scrollByAsync = (el, options) => new Promise((resolve) => {
const start = el.scrollTop;
el.addEventListener('scrollend', () => resolve(el.scrollTop), { once: true });
el.scrollBy(options);
// Falls nicht gescrollt werden konnte, feuert kein scrollend
requestAnimationFrame(() => {
if (el.scrollTop === start) resolve(el.scrollTop);
});
});
const position = await scrollByAsync(box, { top: 300, behavior: 'smooth' });
console.log('Neue Position:', position);
// Wichtig · Fallstricke
- Element muss scrollbar sein: Ohne
overflow: auto/scrollund überstehenden Inhalt passiert nichts, und es gibt auch keinen Fehler. Für die ganze Seitewindow.scrollBy()oderdocument.scrollingElement.scrollBy()verwenden. - Weiches Scrollen:
behavior: "smooth"funktioniert nur mit dem Optionsobjekt, nicht mitscrollBy(x, y). Hat der Nutzerprefers-reduced-motionaktiviert, sollte man auf"auto"bzw."instant"ausweichen. - Mehrere Aufrufe hintereinander: Wird während einer laufenden weichen Animation erneut
scrollBy()aufgerufen, beziehen sich die Beträge je nach Browser auf die aktuelle Zwischenposition. Bei schnellen Klicks kann dadurch ein Karussell „zwischen“ zwei Slides stehen bleiben; CSSscroll-snap-typehilft dagegen. - Nachkommastellen und Grenzen: Werte werden an die möglichen Grenzen (0 bis
scrollHeight - clientHeight) angepasst, Bruchteile von Pixeln können je nach Gerätepixelverhältnis gerundet werden. - Schreibrichtung RTL: In Elementen mit
direction: rtlistscrollLeftam Start 0 und wird nach links negativ; ein positivesleftscrollt weiterhin nach rechts. - Kompatibilität: In allen modernen Browsern verfügbar; das Optionsobjekt und
smoothfehlten in älteren Safari-Versionen (vor 14) bzw. wurden ignoriert. Internet Explorer und Legacy-Edge unterstützenElement.scrollBy()nicht.scrollendist erst seit Kurzem breit verfügbar (Safari erst ab 2025).