Start · Sprachen · JavaScript · Referenz · Window.scrollY

Window.scrollY

Eigenschaft

Liefert die Anzahl der Pixel, um die das Dokument aktuell vertikal gescrollt ist (schreibgeschützt, <code>double</code> mit Subpixel-Genauigkeit).

seit JavaScript Baseline: alle Browser (Alias pageYOffset seit jeh Kategorie: webapi

Signatur

Window.scrollY

Beschreibung

window.scrollY gibt an, wie weit der Inhalt des Dokuments gerade vertikal gescrollt ist, gemessen in CSS-Pixeln ab der Oberkante. Steht die Seite ganz oben, ist der Wert 0. Moderne Browser liefern einen Gleitkommawert mit Subpixel-Genauigkeit, z. B. 431.5, wenn gezoomt ist oder hochauflösende Displays verwendet werden.

Typische Einsatzfälle sind „Nach oben“-Buttons, Kopfzeilen, die sich ab einer bestimmten Scrolltiefe verändern, Lesefortschrittsbalken, das Speichern und Wiederherstellen der Scrollposition und das Umrechnen von Viewport- in Dokumentkoordinaten (element.getBoundingClientRect().top + window.scrollY).

Die Eigenschaft ist schreibgeschützt. Wer die Position ändern will, nutzt window.scrollTo(), window.scrollBy() oder element.scrollIntoView(). window.pageYOffset ist ein Alias mit identischem Wert, der aus Kompatibilitätsgründen erhalten bleibt.

Wichtig: scrollY bezieht sich nur auf das Scrollen des Dokuments bzw. Viewports. Scrollt nur ein einzelner Container (z. B. ein div mit overflow: auto), bleibt scrollY unverändert – dafür gibt es element.scrollTop.

Rückgabewert

Typ
number
Beschreibung
Vertikaler Scrollversatz des Dokuments in CSS-Pixeln (double, ggf. mit Nachkommastellen). 0, wenn nicht gescrollt ist; beim Overscroll/Bounce-Effekt (z. B. Safari auf iOS/macOS) kurzzeitig auch negativ möglich.

Beispiele

Aktuelle Scrollposition auslesen

// Seite z. B. 250 px nach unten gescrollt
console.log(`Vertikal gescrollt: ${window.scrollY}px`);
console.log(window.scrollY === window.pageYOffset); // Alias
Vertikal gescrollt: 250px true

Kopfzeile ab 100 px Scrolltiefe verkleinern (performant mit rAF)

const header = document.querySelector('header');
let ticking = false;

const update = () => {
  header.classList.toggle('is-compact', window.scrollY > 100);
  ticking = false;
};

window.addEventListener('scroll', () => {
  if (!ticking) {
    requestAnimationFrame(update);
    ticking = true;
  }
}, { passive: true });

Lesefortschritt in Prozent berechnen

const progressBar = document.querySelector('#progress');

const getProgress = () => {
  const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
  return maxScroll > 0 ? Math.min(100, (window.scrollY / maxScroll) * 100) : 100;
};

window.addEventListener('scroll', () => {
  progressBar.style.width = `${getProgress().toFixed(1)}%`;
}, { passive: true });

Absolute Dokumentposition eines Elements und Scrollposition wiederherstellen

const section = document.querySelector('#kontakt');
// Viewport-Koordinate + Scrollversatz = Dokument-Koordinate
const absoluteTop = section.getBoundingClientRect().top + window.scrollY;
console.log(`#kontakt beginnt bei ${Math.round(absoluteTop)}px`);

// Position vor dem Verlassen merken und später wiederherstellen
window.addEventListener('pagehide', () => {
  sessionStorage.setItem('scrollPos', String(window.scrollY));
});

const saved = Number(sessionStorage.getItem('scrollPos'));
if (saved) window.scrollTo({ top: saved, behavior: 'instant' });
#kontakt beginnt bei 1840px

// Wichtig · Fallstricke

  • Schreibgeschützt: window.scrollY = 500 scrollt nicht (Zuweisung wird ignoriert bzw. überschreibt nur die Eigenschaft). Zum Scrollen window.scrollTo()/scrollBy() verwenden.
  • Gleitkommawert: Vergleiche wie window.scrollY === maxScroll können wegen Subpixel-Werten fehlschlagen – besser mit Toleranz prüfen, z. B. Math.abs(a - b) < 1.
  • Negative Werte: Beim elastischen Overscroll (Safari) kann scrollY kurzzeitig negativ oder größer als der maximale Wert sein; ggf. mit Math.max(0, …) begrenzen.
  • Layout-Neuberechnung: Das Lesen von scrollY kann bei zuvor geänderten Styles einen synchronen Reflow erzwingen. In scroll-Handlern Lese- und Schreibzugriffe trennen und mit requestAnimationFrame drosseln; Listener als { passive: true } registrieren. Für Sichtbarkeitsprüfungen ist IntersectionObserver meist effizienter.
  • Container-Scrolling: Scrollt nicht das Dokument, sondern ein inneres Element, bleibt scrollY bei 0 – dann element.scrollTop nutzen.
  • Kompatibilität: In allen modernen Browsern verfügbar. Der Internet Explorer kennt nur pageYOffset (ab IE9) bzw. document.documentElement.scrollTop. In Node.js existiert window nicht – bei SSR vorher typeof window !== 'undefined' prüfen.