kulturbanause Blog

Responsive Design, WordPress, Konzeption, HTML, CSS, JS & UX/UI …

Navigation beim Runterscrollen verstecken, beim Hochscrollen anzeigen

Fixierte Navigationsleisten, die sich horizontal über die volle Breite der Website erstrecken sind keine Seltenheit. Um den Blick des Anwenders auf den Inhalt zu lenken und gleichzeitig den wertvollen Platz auf dem Display bestmöglich ausnutzen zu können, wird die Navigation auch häufig beim runterscrollen versteckt und beim hochscrollen wieder angezeigt. Insbesondere sog. Onepager und Landingpages nutzen vermehrt den Effekt. In diesem Beitrag archivieren wir eine CSS/jQuery-Lösung um das Verhalten herzustellen.

Workshops und Seminare von kulturbanause

Adobe XD, Performance, Responsive Design, Sketch, Visual Prototyping, Web Animationen, Corporate Design …

Jetzt Frühbucher-Rabatte sichern!

HTML-Grundaufbau

Die HTML-Struktur besteht in unserem Beispiel lediglich aus einem leeren <nav>-Element.

<nav></nav>

Scroll-Richtung mit jQuery abfragen

Zunächst prüfen wir mit Hilfe von jQuery in welche Richtung der Anwender scrolled. Wenn er nach unten scrolled, wird dem <body> die Klasse down hinzugefügt. Wenn es nach oben geht wird die Klasse entfernt.

var lastScrollTop = 0;
$(window).scroll(function(event){
  var st = $(this).scrollTop();
  if (st > lastScrollTop){
    if (!$('body').hasClass('down')) {
      $('body').addClass('down');
    }
   } else {
     $('body').removeClass('down');
   }

   lastScrollTop = st;

   if ($(this).scrollTop() <= 0) {
     $('body').removeClass('down');
   };
});

Verstecken der Navigation mit CSS

Der CSS-Code ist ebenfalls recht übersichtlich. Die Navigation wird eingefärbt, oben im Browserfenster fixiert und über die volle Breite ausgedehnt. Zusätzlich erhält sie eine feste Höhe und eine Transition, damit sie später animiert aus dem Viewport fährt, sobald per JavaScript die Klasse hinzugefügt wird.

Sobald die Klasse down vorhanden ist, wird mit der CSS-Eigenschaft transform die Navigation um Ihre Höhe nach oben aus dem Viewport geschoben.

nav {
   height:100px;
   background:lime;
   position: fixed;
   top:0;
   right:0;
   left:0;
   transition: transform .25s .1s ease-in-out;
}

.down nav {
   transform: translate3d(0, -100px, 0); // um 100px nach oben verschieben
}

Beispiel anschauen

Jetzt bist du gefragt!

Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freuen wir uns auf deinen Kommentar.

Du kannst diesen Beitrag natürlich auch weiterempfehlen. Wir sind dir für jede Unterstützung dankbar!

Das könnte dich auch interessieren

25 Kommentare

  1. Frank

    Verfasst am 9. Mai 2017 um 9:07 Uhr.

    Sehr cooler Shorttip danke. Hab ich direkt Verwendung dafür :-)

    VG
    Frank

  2. Markus

    Verfasst am 9. Mai 2017 um 10:19 Uhr.

    Wirklich sehr cool und schön.

    Ich frage mich nur…
    Wie könnte man diese Sache umschreiben, wenn der Inhalt von „nav“ unbekannt ist.
    Also wenn man keine fixe Höhe angeben möchte, sondern diese sich u.U. durch den Inhalt ändern könnte?

    Jemand eine Idee?

    LG
    Markus

    • Jakob

      Verfasst am 10. Mai 2017 um 11:18 Uhr.

      Hi Markus,

      dazu entfernst du aus die height Eigenschaft und änderst bei transform die „-100px“ in „-100%“. Also: transform: translate3d(0, -100%, 0);

      Demo: https://jsfiddle.net/cre06a09/

      • Markus

        Verfasst am 10. Mai 2017 um 12:44 Uhr.

        Danke.
        Bin ich gestern auch noch draufgekommen ;-))

  3. Franz Meyer

    Verfasst am 10. Mai 2017 um 15:33 Uhr.

    Sehr interessant! Kann man sicherlich mal gebrauchen.

    Könnte mir bitte jemand erklären, was das folgende bedeutet?

    script
    src=“https://code.jquery.com/jquery-1.12.4.min.js“
    integrity=“sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=“
    crossorigin=“anonymous“>
    script

    • Jonas Hellwig

      Verfasst am 11. Mai 2017 um 10:17 Uhr.

      Hallo Franz, hier wird jQuery über ein CDN geladen. Die Attribute erklärt die jQuery-Doku wie folgt: »The integrity and crossorigin attributes are used for Subresource Integrity (SRI) checking. This allows browsers to ensure that resources hosted on third-party servers have not been tampered with.«

      • Franz Meyer

        Verfasst am 12. Mai 2017 um 9:39 Uhr.

        Hallo Jonas, danke für deine Antwort! Schönen Tag noch!

  4. Timo Klemm

    Verfasst am 23. Mai 2017 um 10:11 Uhr.

    Hallo,
    ist die zweite scrollTop-Abfrage (<=0) nicht überflüssig? Der scrollTop-Wert von window wird eh nie negativ sein und wenn er 0 ist, ist er auf jeden Fall kleiner als lastScrollTop und das wird schon vom vorherigen conditional behandelt.
    Demo:
    https://jsfiddle.net/cre06a09/1/

    Oder überseh ich da irgendetwas?

    • Jonas Hellwig

      Verfasst am 25. Mai 2017 um 10:03 Uhr.

      Hallo Timo, die zweite Abfrage haben wir eingebaut, da man u.a. im Safari über die obere Kante des Browsers hinweg scrollen kann. Damit ist der Wert kleiner Null und die Navigation verschwindet. Ich habe es gerade noch einmal ausprobiert und bei der von dir gekürzten Fassung kann ich somit einen Fehler provozieren, den ich mit unserer Variante nicht ausgelöst bekomme.

  5. Timo Klemm

    Verfasst am 25. Mai 2017 um 11:06 Uhr.

    Ah, ok, das macht Sinn. Trotzdem ist die zweite Abfrage überflüssig, da der scrollTop-Wert ja bereits in der Variable gespeichert ist. Auch die hasClass-Abfrage kann man weglassen, da jQuery das intern eh überprüft.
    Ich hab das nochmal entsprechend umgestellt, jetzt klappt’s auch in Safari:
    https://jsfiddle.net/cre06a09/2/

  6. Christian Schatz

    Verfasst am 13. Juni 2017 um 10:44 Uhr.

    Hallo,
    vielen Dank für das kleine Tutorial.
    Mir ist bloß etwas aufgefallen: Im IE (nicht Edge) funktioniert das Script leider nicht wie gewünscht. Der IE (alle Versionen) berechnet den Wert für scrollTop() zu langsam. Das führt dazu, dass beim scrollen der letzte Wert mehrfach berechnet wird. Somit geht er bei if(st > lastScrollTop) immer in das else und beim runterscrollen wird die Navigation niemals „sticky“!

    Ein Workaround für mich war, dass ich über BrowserDetect den InternetExplorer abgefragt habe und diese Alternative eingebaut habe:

    if(BrowserDetect.browser === ‚IExplorer‘) {
    $(this).bind(‚mousewheel‘, function(e){
    if(e.originalEvent.wheelDelta < 0) {
    //scroll down
    if (!$('.header').hasClass('sticky')) {
    $('.header').addClass('sticky');
    } else {
    //scroll up
    $('header').removeClass('sticky');
    }
    });
    }

    • Julian

      Verfasst am 5. August 2019 um 21:38 Uhr.

      Hallo

      Kann mir jemand sagen wo man diesen Code einfügen muss damit es auch im Internet Explorer funktioniert?
      Ich habe schon viele verschiedene Codes ausprobiert und keiner funktioniert im IE11. Mit diesem Post hatte ich wieder Hoffnung eine Lösung gefunden zu haben, aber wenn ich den im script einfüge geht nichts mehr.

  7. Thomas

    Verfasst am 12. September 2017 um 15:12 Uhr.

    Hallo,
    gutes Tutorial.
    Was muß wo hinzugefügt / abgeändert werden, wenn das Verstecken der Navigation erst einsetzen soll, wenn schon etwas gescrollt wurde, z.B. nach 200px scrollen die Navigation ausgeblendet werden soll?

    • Sebastian

      Verfasst am 6. Januar 2018 um 20:23 Uhr.

      Ändere die Variable lastScrollTop = 0 z.B. zu lastScrollTop = 200px;
      Damit sollte es funktionieren

  8. Jan Wadehn

    Verfasst am 22. September 2017 um 11:47 Uhr.

    Tolles Skript! Absolut!

    Gibt es eine Möglichkeit, dass erst wieder ab zB Scrollwert 250 angezeigt wird, also nicht bei jedem upscroll?

    Danke für einen Tipp!

  9. Marco Rieser

    Verfasst am 12. Januar 2018 um 19:08 Uhr.

    Super, ich würde das Ganze aber mit debouncing schreiben, dann ist das nicht so ressourcenhungrig.

  10. Patrick

    Verfasst am 25. Mai 2018 um 0:33 Uhr.

    Hallo,
    gibt es da keine Lösung um komplett auf Javascript zu verzichten? Denn wenn Javascript deaktiviert ist, würde dein Code nicht funktioniert. Bitte um Antwort. Vielen Dank

    • Jonas Hellwig

      Verfasst am 27. Mai 2018 um 8:43 Uhr.

      Nein, eine Lösung ohne JavaScript gibt es nicht. Was allerdings auch nicht tragisch ist, wenn die Website sauber nach dem Progressive Enhancement-Konzept aufgebaut ist.

  11. Stephan

    Verfasst am 30. November 2018 um 0:11 Uhr.

    Hallo, gibt es die Möglichkeit zu sagen das die leiste erst wieder erscheinen soll wenn man ganz nach oben gescrollt hat? Danke

    • Jonas Hellwig

      Verfasst am 30. November 2018 um 9:48 Uhr.

      Wenn die Navigation beim runterscrollen verschwinden soll und dann beim hochscrollen erst ganz oben sichtbar sein soll, musst du doch gar nichts machen. Das ist ja der Standard … oder?

  12. marie

    Verfasst am 7. Mai 2019 um 14:17 Uhr.

    Hallo,

    ich wollet mich erstmal bedanken für die tollen Tipps!
    Ich habe folgende Frage, im header Bereich habe ich ein Logo (relativ groß), das über den Slider hervorsteht (im Vordergrund), wenn ich die Seite nach unten scrolle, geht das Element/Logo mit, allerdings soll in Hintergrund bzw. rücken. Im Content ist schon der Test und das Logo soll hinter dem Text sein. Wäre es möglich? Ich habe schon dem Logo z-index:1 vergeben aber, wenn ich den anderen Elementen auch 1 oder 2 vergebe ändert sich nichts.

  13. Henning Famulla

    Verfasst am 4. Juni 2019 um 11:18 Uhr.

    Hey,

    ich habe die ersten 3 Google Seiten nach einer Sticky Navbar Lösung durchsucht, aber nichts gefunden was funktioniert.
    Ich arbeite mit einem Baukasten (Siquando ProWeb3) und habe nur einige HTML,PHP Codes eingefügt, da ich nicht so der Programmierer bin.
    Kann mir evt. jemand einen Tipp geben, wie ich das auf der Homepage http://www.ahaf.de umsetzen kann?
    Danke für jede Hilfe!

    Beste Grüße

    Henning Famulla

    • Jonas Hellwig

      Verfasst am 7. Juni 2019 um 9:41 Uhr.

      Hallo Henning, das Snippet hier im Blog ist standardkonform und sollte funktionieren. Möglicherweise beinhaltet deine Umsetzung auf Grundlage einer Vorlage aber Code, der Inkompatibilitäten verursacht. Das lässt sich allerdings nur mit entsprechender Recherche in Erfahrung bringen.

Kommentar verfassen

Dieser Blog lebt vom Feedback der Besucher! Also los, mach mit!
Bitte habe Verständnis dafür, dass Kommentare die mit dem Inhalt dieses Beitrags nichts zu tun haben, gelöscht werden.