Skip to content

Alles für WordPress, Webentwicklung — und mehr

🖱 Sanftes scrollen zum anker: CSS, JavaScript und jQuery - drei funktionierende ansätze

🖱 Sanftes scrollen zum anker: CSS, JavaScript und jQuery - drei funktionierende ansätze

Der Nutzer klickt auf einen Link mit einem Anker, und die Seite springt sofort zur Zielposition. Keine Animation, keine Sanftheit, kein Verständnis dafür, wo man gelandet ist. Der abrupte Übergang ist desorientierend, besonders auf langen Landingpages und in Dokumentationen.

Sanftes Scrollen zu Ankern einzubauen dauert 5 Minuten. Aber der Teufel steckt im Detail: Der Link könnte von einer externen Seite kommen, die URL enthält bereits einen Hash, und oben gibt es einen fixierten Header, der den Anker verdeckt. Ein einfaches scroll-behavior: smooth löst diese Nuancen nicht.

Nachfolgend finden Sie drei funktionierende Ansätze: reines CSS, natives JavaScript und jQuery. Jeweils mit Code, den Sie kopieren und in Ihr Projekt einfügen können. Zusätzlich behandeln wir externe Übergänge separat, damit das Scrollen auch funktioniert, wenn der Nutzer von einer anderen Seite oder aus den Suchergebnissen kommt.

💡 Kurzüberblick:

  • Sanftes Scrollen mit einer CSS-Zeile aktivieren, ganz ohne JavaScript
  • Offset für fixierten Header mit scroll-margin-top hinzufügen
  • Natives JS mit scrollIntoView für externe Übergänge und Feinabstimmung schreiben
  • Die jQuery-Variante mit animate() abdecken, wenn Sie individuelle Geschwindigkeit und Kontrolle benötigen
  • Externen Hash behandeln: Seite geladen, Anker in der URL, und sanft zum Ziel scrollen

Warum sanftes Scrollen wichtig ist

Abruptes Springen zu einem Anker ist desorientierend. Der Nutzer verliert den Kontext: Wo war ich, wo bin ich gelandet, was habe ich verpasst? Sanftes Scrollen erhält die räumliche Orientierung und gibt dem Auge etwas, dem es folgen kann, während sich die Seite bewegt.

Aus Wahrnehmungssicht wirkt eine Seite mit sanftem Scrollen poliert. Das macht sich besonders auf langen Seiten bemerkbar: Landingpages, Dokumentationen, FAQ-Bereiche, Artikel-Inhaltsverzeichnisse. Der Nutzer klickt im Menü auf „Preise", und die Seite ruckelt nicht, sondern gleitet sanft zum Preisblock.

Technisch gliedert sich die Aufgabe in zwei Teile: Scrollen beim Klick auf einen internen Link (Nutzer befindet sich bereits auf der Seite) und Scrollen bei einem externen Übergang (URL enthält bereits #anchor). Im zweiten Fall springt der Browser standardmäßig sofort zum Anker, noch bevor die Seite vollständig geladen ist, und das muss abgefangen werden.

CSS scroll-behavior, eine Zeile statt eines Skripts

Der einfachste und modernste Ansatz. Browser beherrschen sanftes Scrollen nativ, eine CSS-Regel genügt:

1html {
2 scroll-behavior: smooth;
3}

Das ist alles. Jeder Übergang per Ankerlink wird sanft. Kein JavaScript, keine Bibliotheken.

Unterstützung: alle modernen Browser seit 2022: Chrome 61+, Firefox 36+, Safari 15.4+, Edge 79+. Die einzige Ausnahme ist IE11, dessen Traffic-Anteil jedoch gegen null geht.

Fixierter Header: scroll-margin-top

Wenn ein fixierter Header (Sticky Header) über dem Inhalt hängt, landet der Anker nach dem Scrollen darunter. Beheben Sie das mit einer Zeile:

1h2, h3, [id] {
2 scroll-margin-top: 80px; /* header height + offset */
3}

Der Browser fügt beim Scrollen zum Zielelement automatisch einen Offset hinzu. Früher behalf man sich mit Hacks über padding-top und negativem margin, heute ist das nicht mehr nötig.

Grenzen des reinen CSS

Der CSS-Ansatz bietet keine Kontrolle über Animationsgeschwindigkeit und Easing-Funktion. Der Browser nutzt eine eingebaute Kurve, meist ease-in-out. Wenn Sie eine individuelle Geschwindigkeit oder nichtlineare Animation benötigen, steigen Sie auf JavaScript um.

Natives JavaScript: scrollIntoView

Wenn CSS allein nicht ausreicht, kommt die Methode scrollIntoView() mit der Option behavior: 'smooth' zur Hilfe:

1document.querySelectorAll('a[href^="#"]').forEach(anchor => {
2 anchor.addEventListener('click', function(e) {
3 e.preventDefault();
4 const target = document.querySelector(this.getAttribute('href'));
5 if (target) {
6 target.scrollIntoView({
7 behavior: 'smooth',
8 block: 'start'
9 });
10 }
11 });
12});

Dieser Code fängt Klicks auf alle Links mit # ab, unterbricht den Standardübergang und startet das sanfte Scrollen. Funktioniert ohne jQuery und ohne zusätzliche Bibliotheken.

Der Vorteil: Sie können es programmatisch steuern: Geschwindigkeit über CSS scroll-behavior auf <html> ändern, Bedingungen hinzufügen (zum Beispiel bestimmte Links ausschließen), mit scroll-margin-top für den Header kombinieren.

Der Nachteil: scrollIntoView erlaubt es nicht, die Animationsgeschwindigkeit direkt festzulegen. Für eine individuelle Scroll-Dauer (etwa 800 ms statt der browserüblichen ca. 500 ms) benötigen Sie entweder jQuery oder manuelles requestAnimationFrame.

JQuery animate, volle Kontrolle über die Animation

Wenn das Projekt bereits jQuery nutzt oder Sie eine Feinabstimmung benötigen (Geschwindigkeit, Offset für Header, Link-Filterung), hier das aktuelle Skript. Nachfolgend eine adaptierte Version des klassischen Ansatzes, umgeschrieben für modernes jQuery:

1jQuery(document).ready(function($) {
2 // Smooth scroll on anchor link click
3 $('a[href*="#"]:not([href="#"])').on('click', function() {
4 if (
5 location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '')
6 && location.hostname === this.hostname
7 ) {
8 var target = $(this.hash);
9 target = target.length ? target : $('[name="' + this.hash.slice(1) + '"]');
10 if (target.length) {
11 $('html, body').animate({
12 scrollTop: target.offset().top - 80
13 }, 800);
14 return false;
15 }
16 }
17 });
18
19 // Scroll on external transition with hash in URL
20 if (window.location.hash) {
21 var hash = window.location.hash.substring(1);
22 var $target = $('#' + hash);
23 if ($target.length) {
24 setTimeout(function() {
25 $('html, body').animate({
26 scrollTop: $target.offset().top - 80
27 }, 800);
28 }, 100);
29 }
30 }
31});

Was sich hier im Vergleich zu alten Versionen, die in Blogs kursieren, geändert hat:

  • .bind() wurde durch .on() ersetzt, .bind() wurde in jQuery 3.0 als veraltet markiert und wird in jQuery 4.0 entfernt.
  • Selektor 'a:not(.spu-clickable)[href*="#"]:not([href="#"])' vereinfacht, die spezifische Klasse .spu-clickable bezog sich auf ein bestimmtes Plugin (Popups by OptinMonster) und wird im Allgemeinen nicht benötigt.
  • jQuery(window).bind("load", ...) entfernt, der zweite Teil des Skripts für den externen Hash lebt jetzt in $(document).ready() und benötigt kein separates load-Ereignis.
  • Verzögerung setTimeout(..., 100) hinzugefügt, damit das DOM garantiert gerendert ist, bevor die Ankerposition berechnet wird (relevant für Seiten mit Lazy Loading von Bildern und dynamischen Inhalten).

Wo Sie den Code einfügen

Drei Optionen zur Auswahl:

  • Über die Theme-Datei. Fügen Sie das Skript per wp_enqueue_script() in die functions.php ein, die Standardmethode für ein Child-Theme.
  • Plugin Code Snippets. Fügen Sie den Code als neuen Snippet mit automatischer Ausführung ein, er geht bei einem Theme-Update nicht verloren.
  • Custom-JS-Plugin. Wenn die Seite bereits ein Plugin zum Einfügen von beliebigem JavaScript nutzt (zum Beispiel WPCode), fügen Sie den Code dort hinzu.

Umgang mit externem Übergang mit Hash, detaillierte Aufschlüsselung

Der kniffligste Teil der Aufgabe. Der Nutzer folgt einem Link https://site.com/page/#pricing von einer anderen Seite oder aus der Suche. Der Browser springt standardmäßig sofort zu #pricing, sobald das Element im DOM erscheint, ohne Animation und oft bevor die Seite vollständig geladen ist.

Das obige jQuery-Skript löst das in zwei Schritten:

  • Erkennt das Vorhandensein eines Hash über window.location.hash. Wenn ein Hash existiert, wird sein Wert ausgelesen (ohne #).
  • Findet das Ziel und scrollt. $('#' + hash) findet das Element, setTimeout gibt der Seite Zeit zum Rendern, animate() führt mit 80 Pixel Offset zum Ziel.

Die 100 Millisekunden Verzögerung sind ein Erfahrungswert. Auf schnellen Seiten reichen 50 ms, auf schweren (Landingpages mit Hintergrundvideo, Karten, Diagrammen) sollte man besser auf 200-300 ms erhöhen. Alternative: auf das window.load-Ereignis warten statt auf document.ready, aber dann erfolgt das Scrollen erst, nachdem alle Bilder geladen sind, was dauern kann.

Was tun, wenn der Anker kein Ziel findet

Manchmal zeigt der Hash in der URL auf ein nicht existierendes Element. Zum Beispiel hat sich der Nutzer vertippt oder die Seite wurde geändert. In diesem Fall schlägt weder der CSS- noch der JS-Ansatz mit einem Fehler fehl, es passiert einfach nichts. Der Browser ignoriert den nicht existierenden Anker. Auch das sanfte Scrollen läuft stillschweigend ins Leere (die Bedingung if (target.length) lässt es nicht weitergehen).

Vergleich der drei Ansätze

Kriterium

CSS scroll-behavior

JS scrollIntoView

jQuery animate

Implementierungsaufwand

1 Zeile CSS

10-15 Zeilen JS

25-30 Zeilen JS + jQuery

Geschwindigkeitskontrolle

Nein

Nein (Browser-Standard)

Ja (ms)

Externer Hash

Ja, nativ

Erfordert zusätzlichen Code

Erfordert zusätzlichen Code

Header-Offset

scroll-margin-top

scroll-margin-top

Manuell in offset().top

Abhängigkeiten

Keine

Keine

jQuery 3.x

Browser-Unterstützung

96%+

96%+

99%+ (mit jQuery)

Für die meisten modernen Projekte ist der CSS-Ansatz optimal: eine Zeile, null Abhängigkeiten, native Performance. Wenn Sie einen Offset für den Header benötigen, fügen Sie scroll-margin-top hinzu. Wenn Sie eine individuelle Geschwindigkeit oder Unterstützung für Uralt-Browser brauchen, jQuery mit animate().

Nachfolgend ein Video mit einer Live-Demonstration aller drei Ansätze, von CSS bis jQuery:

⁉️🤔 Häufig gestellte Fragen

Warum funktioniert sanftes Scrollen auf Mobilgeräten nicht?

In iOS Safari vor Version 15.4 wurde scroll-behavior: smooth nicht unterstützt. Inzwischen ist die Unterstützung vorhanden (Safari 15.4+, März 2022). Wenn das Scrollen auf alten iPhones nicht funktioniert, fügen Sie einen JavaScript-Fallback mit scrollIntoView oder requestAnimationFrame hinzu. Prüfen Sie auch, ob das Scrollen nicht durch overflow: hidden auf body blockiert wird, manche Mobilmenüs setzen das beim Öffnen. Stand Juni 2026 liegt die globale Unterstützung für scroll-behavior bei 96,3% der Browser (Daten von Can I Use).

Wie lässt sich sanftes Scrollen nicht zu einem Anker, sondern zu einem beliebigen Element per Button-Klick realisieren?

Geben Sie dem Element eine id und nutzen Sie dasselbe JavaScript, aber gebunden an einen Button statt an einen Ankerlink. Zum Beispiel „Zurück nach oben"-Button: document.querySelector('#back-to-top').addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' })). Für die jQuery-Variante: $('#back-to-top').on('click', () => $('html, body').animate({ scrollTop: 0 }, 600)). Keine Anker nötig, scrollen Sie zu Koordinaten.

Ist es 2026 nötig, jQuery nur für sanftes Scrollen einzubinden?

Nein. jQuery wiegt in der min-Version etwa 87 KB (30 KB gzip). Wenn jQuery sonst nirgends auf der Seite genutzt wird, ist es nicht sinnvoll, es nur für einen Scroll-Effekt einzubinden. Nutzen Sie den CSS-Ansatz mit scroll-behavior: smooth oder natives scrollIntoView. jQuery ist nur dann gerechtfertigt, wenn die Seite bereits darauf aufbaut (jQuery-Themes, Legacy-Projekte) und Sie Scrollen zur bestehenden Codebasis hinzufügen möchten.

Kann man das Scrollen mit unterschiedlicher Geschwindigkeit animieren, erst schnell, dann langsam?

Ja, über $.animate() mit jQuery UI oder über requestAnimationFrame mit einer Easing-Funktion. Das standardmäßige jQuery animate() nutzt eine lineare oder Swing-Funktion. Für nicht standardmäßige Kurven binden Sie jquery.easing ein oder schreiben eine eigene Schleife auf requestAnimationFrame mit einer benutzerdefinierten Easing-Funktion, zum Beispiel easeInOutQuad. Das gibt Ihnen volle Kontrolle über Geschwindigkeit und Bewegungsverlauf und erfordert keine externen Bibliotheken.

Wie überprüfe ich, ob das Scrollen bei einem externen Übergang mit Hash funktioniert?

Öffnen Sie einen neuen Tab, fügen Sie die URL mit Anker ein (zum Beispiel https://yoursite.com/page/#contacts) und drücken Sie Enter. Die Seite sollte laden und sanft zum Block scrollen. Zweite Möglichkeit: Führen Sie in der Browser-Konsole auf der geöffneten Seite location.hash = '#contacts' aus. Wenn das Scrollen sanft ist, funktioniert das Skript. Wenn die Seite abrupt gesprungen ist, ist der Handler für externe Hashes nicht konfiguriert.

Welchen Ansatz Sie für Ihre Aufgabe wählen sollten

Wenn die Seite modern ist, ohne jQuery, deckt CSS scroll-behavior: smooth die allermeisten Szenarien ab. Eine Zeile, sofortiges Ergebnis. Fügen Sie scroll-margin-top für den Header hinzu, und Sie sind fertig.

Wenn die Seite auf WordPress mit jQuery im Theme läuft, jQuery-Skript mit animate(). Gibt Kontrolle über Geschwindigkeit und Offset, behandelt externe Übergänge, kollidiert nicht mit anderen Plugins.

Wenn Sie von Grund auf neu schreiben und keine Bibliothek einbinden möchten, natives scrollIntoView() mit externem Hash-Handler. Die goldene Mitte: sauber, schnell, keine Abhängigkeiten.

Nehmen Sie den Code aus dem Artikel, fügen Sie ihn in Ihr Projekt ein und prüfen Sie den externen Übergang, das ist der einzige Fall, den man beim Testen leicht übersieht.