Wenn Sie schon einmal position: sticky für ein Sidebar-Menü oder Inhaltsverzeichnis festgelegt und dann zugesehen haben, wie es einfach… nicht kleben bleibt, sind Sie damit nicht allein.

Warum CSS position: sticky nicht mehr funktioniert (Und How overflow on html/body Breaks It)

In diesem Artikel gehe ich anhand eines echten Falls, auf den ich gestoßen bin, auf Folgendes ein:

  • Den tatsächlichen Grund, warum Positionierung mit Sticky fehlschlägt
  • Wie man das Problem in den DevTools richtig diagnostiziert
  • Warum Overflow auf html und body der Auslöser war – und wie man es behebt

Das Ganze mit einer nachvollziehbaren Schritt-für-Schritt-Aufteilung.


Das häufige Missverständnis über position: sticky

Vielleicht haben Sie CSS, das absolut korrekt aussieht, wie dieses:

css
.category-toc {
  position: sticky;
  top: 100px;
}

Und Sie stoßen trotzdem auf dieselben Beschwerden:

  • position: sticky ist gesetzt, aber es passiert nichts
  • top ist definiert
  • Kein overflow: hidden bei irgendeinem Elternelement – oder das glauben Sie zumindest

Wenn es immer noch nicht kleben bleibt, stehen die Chancen gut, dass die Deklaration selbst in Ordnung ist, aber etwas Strukturelles sie im Hintergrund zunichtemacht.


Was Sie zuerst prüfen sollten (Diagnose mit den DevTools)

Öffnen Sie die DevTools in Chrome (oder Edge), gehen Sie zum Reiter Console und führen Sie dies aus:

js
const el = document.querySelector('.category-toc');

getComputedStyle(el).position
getComputedStyle(el).top
getComputedStyle(el).overflow

[!NOTE] Wenn Sie das erste Mal etwas in die Konsole einfügen, müssen Sie eventuell manuell „allow pasting“ eingeben, bevor Chrome Ihnen das Einfügen erlaubt.

Wie ein gesundes Ergebnis aussieht

txt
position: "sticky"
top: "100px"
overflow: "visible"

Wenn diese Werte in Ordnung aussehen, ist die Sticky-Deklaration selbst nicht das Problem.

Bleibt es nach dieser Bestätigung weiterhin unbeweglich, ist der nächste Verdächtiger woanders zu suchen.

Die häufigste Ursache: Overflow auf html / body

In meinem Fall waren die Overflow-Einstellungen für html und body der Auslöser.

Eine Überprüfung über die Konsole ergab etwa Folgendes:

js
{
  scrollingElement: 'html',
  htmlOverflow: 'hidden auto',
  bodyOverflow: 'auto'
}

Was effektiv Folgendes bedeutete:

  • html: overflow-x: hidden; overflow-y: auto
  • body: overflow: auto

Mit anderen Worten: Zwei separate Scroll-Container waren gleichzeitig aktiv.

Warum Overflow auf html/body Sticky zerstört

position: sticky berechnet seine Position relativ zu:

  • Dem nächstgelegenen scrollenden Vorfahren oder
  • Dem Viewport, falls kein solcher existiert

Aber wenn:

  • html scrollbar ist
  • body ebenfalls scrollbar ist
  • Und sich darüber noch ein Wrapper-Element befindet

…kann der Browser nicht mehr zuverlässig ermitteln, an welchem Container das Sticky-Element verankert sein soll. Das praktische Ergebnis ist ein Element, das die Sticky-Positionierung scheinbar komplett ignoriert.

Die Lösung: Das HTML-Element das Scrollen übernehmen lassen und Body in den Normalfluss zurückversetzen

Die zuverlässigste Lösung sieht so aus:

css
html {
  overflow-x: hidden;
  overflow-y: auto;
}

body {
  overflow: visible;
}

Wichtige Punkte

  • Das vertikale Scrollen ausschließlich auf html konsolidieren
  • Kein overflow: auto auf body setzen
  • overflow-x: hidden zur Verhinderung des horizontalen Scrollens kann bedenkenlos beibehalten werden

Sobald diese Änderung vorgenommen wurde, funktionierte das zuvor hartnäckig verweigerte Sticky-Element sofort wieder.


Zuerst live in der Konsole testen

Bevor Sie Ihr tatsächliches CSS anfassen, können Sie dieses Verhalten temporär in der Konsole testen:

js
document.documentElement.style.overflowY = 'auto';
document.documentElement.style.overflowX = 'hidden';
document.body.style.overflow = 'visible';

Wenn Sticky nach dem Ausführen zu funktionieren beginnt, haben Sie bestätigt, dass Overflow die Ursache ist.

Achten Sie auf diese häufigen Regressionen

Die Sticky-Positionierung kann erneut ausfallen, wenn später eine der folgenden Stellen in Ihrer Codebasis auftaucht:

  • Modal-Implementierungen, die html { overflow: hidden } dauerhaft aktiv lassen
  • Layout-Code, der body { overflow: auto } aus unzusammenhängenden Gründen setzt
  • Ein height: 100vh-Wrapper in Kombination mit einer eigenen Overflow-Steuerung

Wenn Sie das Scrollen sperren müssen, während ein Modal geöffnet ist, ist es sicherer, overflow: auto als Standardzustand beizubehalten und erst dann auf hidden umzuschalten, wenn das Modal aktiv ist:

css
html {
  overflow-y: auto;
  overflow-x: hidden;
}

.modal-open html {
  overflow: hidden;
}

Zusammenfassung: Was zu prüfen ist, wenn Sticky nicht kleben bleibt

  • Gehen Sie nicht automatisch davon aus, dass alles sicher ist, nur weil position und top korrekt aussehen
  • Prüfen Sie overflow auf html und body, und nicht nur beim unmittelbaren Elternelement
  • Stellen Sie sicher, dass es nur einen aktiven Scroll-Container auf der Seite gibt

Meistens liegen Probleme mit der Sticky-Positionierung eher daran, von wo aus die Seite tatsächlich scrollt, als an einem Fehler in der Schreibweise von Sticky selbst.

Hoffentlich erspart dies jemand anderem dieselbe nervige Debugging-Sitzung.